WrappedApplicationKey.java revision 52c15f1699e60c0701cc21a69847a005efe87bc9
1/*
2 * Copyright (C) 2018 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.recovery;
18
19import android.annotation.NonNull;
20import android.annotation.SystemApi;
21import android.os.Parcel;
22import android.os.Parcelable;
23
24import com.android.internal.util.Preconditions;
25
26/**
27 * Helper class with data necessary recover a single application key, given a recovery key.
28 *
29 * <ul>
30 *   <li>Alias - Keystore alias of the key.
31 *   <li>Encrypted key material.
32 * </ul>
33 *
34 * Note that Application info is not included. Recovery Agent can only make its own keys
35 * recoverable.
36 *
37 * @hide
38 */
39@SystemApi
40public final class WrappedApplicationKey implements Parcelable {
41    private String mAlias;
42    // The only supported format is AES-256 symmetric key.
43    private byte[] mEncryptedKeyMaterial;
44
45    // IMPORTANT! PLEASE READ!
46    // -----------------------
47    // If you edit this file (e.g., to add new fields), please MAKE SURE to also do the following:
48    // - Update the #writeToParcel(Parcel) method below
49    // - Update the #(Parcel) constructor below
50    // - Update android.security.keystore.recovery.KeyChainSnapshotTest to make sure nobody
51    //     accidentally breaks your fields in the Parcel in the future.
52    // - Update com.android.server.locksettings.recoverablekeystore.serialization
53    //     .KeyChainSnapshotSerializer to correctly serialize your new field
54    // - Update com.android.server.locksettings.recoverablekeystore.serialization
55    //     .KeyChainSnapshotSerializer to correctly deserialize your new field
56    // - Update com.android.server.locksettings.recoverablekeystore.serialization
57    //     .KeychainSnapshotSerializerTest to make sure nobody breaks serialization of your field
58    //     in the future.
59
60    /**
61     * Builder for creating {@link WrappedApplicationKey}.
62     */
63    public static class Builder {
64        private WrappedApplicationKey mInstance = new WrappedApplicationKey();
65
66        /**
67         * Sets Application-specific alias of the key.
68         *
69         * @param alias The alias.
70         * @return This builder.
71         */
72        public Builder setAlias(@NonNull String alias) {
73            mInstance.mAlias = alias;
74            return this;
75        }
76
77        /**
78         * @deprecated AOSP does not associate keys with accounts. This may be done by system app.
79         */
80        @Deprecated
81        public Builder setAccount(@NonNull byte[] account) {
82            return this;
83        }
84
85        /**
86         * Sets key material encrypted by recovery key.
87         *
88         * @param encryptedKeyMaterial The key material
89         * @return This builder
90         */
91
92        public Builder setEncryptedKeyMaterial(@NonNull byte[] encryptedKeyMaterial) {
93            mInstance.mEncryptedKeyMaterial = encryptedKeyMaterial;
94            return this;
95        }
96
97        /**
98         * Creates a new {@link WrappedApplicationKey} instance.
99         *
100         * @return new instance
101         * @throws NullPointerException if some required fields were not set.
102         */
103        @NonNull public WrappedApplicationKey build() {
104            Preconditions.checkNotNull(mInstance.mAlias);
105            Preconditions.checkNotNull(mInstance.mEncryptedKeyMaterial);
106            return mInstance;
107        }
108    }
109
110    private WrappedApplicationKey() { }
111
112    /**
113     * Deprecated - consider using Builder.
114     * @hide
115     */
116    public WrappedApplicationKey(@NonNull String alias, @NonNull byte[] encryptedKeyMaterial) {
117        mAlias = Preconditions.checkNotNull(alias);
118        mEncryptedKeyMaterial = Preconditions.checkNotNull(encryptedKeyMaterial);
119    }
120
121    /**
122     * Application-specific alias of the key.
123     *
124     * @see java.security.KeyStore.aliases
125     */
126    public @NonNull String getAlias() {
127        return mAlias;
128    }
129
130    /** Key material encrypted by recovery key. */
131    public @NonNull byte[] getEncryptedKeyMaterial() {
132        return mEncryptedKeyMaterial;
133    }
134
135    /**
136     * @deprecated AOSP does not associate keys with accounts. This may be done by system app.
137     */
138    @Deprecated
139    public @NonNull byte[] getAccount() {
140        return new byte[0];
141    }
142
143    public static final Parcelable.Creator<WrappedApplicationKey> CREATOR =
144            new Parcelable.Creator<WrappedApplicationKey>() {
145                public WrappedApplicationKey createFromParcel(Parcel in) {
146                    return new WrappedApplicationKey(in);
147                }
148
149                public WrappedApplicationKey[] newArray(int length) {
150                    return new WrappedApplicationKey[length];
151                }
152            };
153
154    @Override
155    public void writeToParcel(Parcel out, int flags) {
156        out.writeString(mAlias);
157        out.writeByteArray(mEncryptedKeyMaterial);
158    }
159
160    /**
161     * @hide
162     */
163    protected WrappedApplicationKey(Parcel in) {
164        mAlias = in.readString();
165        mEncryptedKeyMaterial = in.createByteArray();
166    }
167
168    @Override
169    public int describeContents() {
170        return 0;
171    }
172}
173