181ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry/*
2291bd32c9e547a5862d28f3a68ed2f514ccfbd86Robert Berry * Copyright (C) 2018 The Android Open Source Project
381ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry *
481ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry * Licensed under the Apache License, Version 2.0 (the "License");
581ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry * you may not use this file except in compliance with the License.
681ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry * You may obtain a copy of the License at
781ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry *
881ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry *      http://www.apache.org/licenses/LICENSE-2.0
981ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry *
1081ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry * Unless required by applicable law or agreed to in writing, software
1181ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry * distributed under the License is distributed on an "AS IS" BASIS,
1281ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1381ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry * See the License for the specific language governing permissions and
1481ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry * limitations under the License.
1581ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry */
1681ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry
1781ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berrypackage android.security.keystore.recovery;
1881ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry
1981ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berryimport android.annotation.NonNull;
20f8ae5deba2911b7bc8441df31c0504eaaa687addDmitry Dementyevimport android.annotation.SystemApi;
2181ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berryimport android.os.Parcel;
2281ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berryimport android.os.Parcelable;
2381ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry
2481ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berryimport com.android.internal.util.Preconditions;
2581ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry
2681ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry/**
2781ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry * Helper class with data necessary recover a single application key, given a recovery key.
2881ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry *
2981ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry * <ul>
3081ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry *   <li>Alias - Keystore alias of the key.
3181ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry *   <li>Encrypted key material.
3281ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry * </ul>
3381ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry *
3481ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry * Note that Application info is not included. Recovery Agent can only make its own keys
3581ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry * recoverable.
3681ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry *
3781ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry * @hide
3881ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry */
39f8ae5deba2911b7bc8441df31c0504eaaa687addDmitry Dementyev@SystemApi
4081ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berrypublic final class WrappedApplicationKey implements Parcelable {
4181ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    private String mAlias;
4281ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    // The only supported format is AES-256 symmetric key.
4381ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    private byte[] mEncryptedKeyMaterial;
4481ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry
4552c15f1699e60c0701cc21a69847a005efe87bc9Robert Berry    // IMPORTANT! PLEASE READ!
4652c15f1699e60c0701cc21a69847a005efe87bc9Robert Berry    // -----------------------
4752c15f1699e60c0701cc21a69847a005efe87bc9Robert Berry    // If you edit this file (e.g., to add new fields), please MAKE SURE to also do the following:
4852c15f1699e60c0701cc21a69847a005efe87bc9Robert Berry    // - Update the #writeToParcel(Parcel) method below
4952c15f1699e60c0701cc21a69847a005efe87bc9Robert Berry    // - Update the #(Parcel) constructor below
5052c15f1699e60c0701cc21a69847a005efe87bc9Robert Berry    // - Update android.security.keystore.recovery.KeyChainSnapshotTest to make sure nobody
5152c15f1699e60c0701cc21a69847a005efe87bc9Robert Berry    //     accidentally breaks your fields in the Parcel in the future.
5252c15f1699e60c0701cc21a69847a005efe87bc9Robert Berry    // - Update com.android.server.locksettings.recoverablekeystore.serialization
5352c15f1699e60c0701cc21a69847a005efe87bc9Robert Berry    //     .KeyChainSnapshotSerializer to correctly serialize your new field
5452c15f1699e60c0701cc21a69847a005efe87bc9Robert Berry    // - Update com.android.server.locksettings.recoverablekeystore.serialization
5552c15f1699e60c0701cc21a69847a005efe87bc9Robert Berry    //     .KeyChainSnapshotSerializer to correctly deserialize your new field
5652c15f1699e60c0701cc21a69847a005efe87bc9Robert Berry    // - Update com.android.server.locksettings.recoverablekeystore.serialization
5752c15f1699e60c0701cc21a69847a005efe87bc9Robert Berry    //     .KeychainSnapshotSerializerTest to make sure nobody breaks serialization of your field
5852c15f1699e60c0701cc21a69847a005efe87bc9Robert Berry    //     in the future.
5952c15f1699e60c0701cc21a69847a005efe87bc9Robert Berry
6081ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    /**
6181ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry     * Builder for creating {@link WrappedApplicationKey}.
6281ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry     */
6381ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    public static class Builder {
640916e7ca44aba5e6c89d75007da805697fdace9eDmitry Dementyev        private WrappedApplicationKey mInstance = new WrappedApplicationKey();
6581ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry
6681ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry        /**
6781ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry         * Sets Application-specific alias of the key.
6881ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry         *
6981ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry         * @param alias The alias.
7081ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry         * @return This builder.
7181ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry         */
7281ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry        public Builder setAlias(@NonNull String alias) {
7381ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry            mInstance.mAlias = alias;
7481ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry            return this;
7581ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry        }
7681ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry
7781ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry        /**
78c157e21249b01cca18e6712d69c719f245db51a7Robert Berry         * @deprecated AOSP does not associate keys with accounts. This may be done by system app.
793990ee1c9fcd8f801220edec94e6bef3009809b5Jeff Sharkey         * @removed
800916e7ca44aba5e6c89d75007da805697fdace9eDmitry Dementyev         */
81291bd32c9e547a5862d28f3a68ed2f514ccfbd86Robert Berry        @Deprecated
820916e7ca44aba5e6c89d75007da805697fdace9eDmitry Dementyev        public Builder setAccount(@NonNull byte[] account) {
83745d2c98f9467f1befb7ec3a6c485333d4f1b437Dmitry Dementyev            throw new UnsupportedOperationException();
840916e7ca44aba5e6c89d75007da805697fdace9eDmitry Dementyev        }
850916e7ca44aba5e6c89d75007da805697fdace9eDmitry Dementyev
860916e7ca44aba5e6c89d75007da805697fdace9eDmitry Dementyev        /**
8781ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry         * Sets key material encrypted by recovery key.
8881ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry         *
8981ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry         * @param encryptedKeyMaterial The key material
9081ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry         * @return This builder
9181ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry         */
9281ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry
9381ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry        public Builder setEncryptedKeyMaterial(@NonNull byte[] encryptedKeyMaterial) {
9481ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry            mInstance.mEncryptedKeyMaterial = encryptedKeyMaterial;
9581ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry            return this;
9681ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry        }
9781ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry
9881ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry        /**
9981ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry         * Creates a new {@link WrappedApplicationKey} instance.
10081ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry         *
10181ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry         * @return new instance
10281ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry         * @throws NullPointerException if some required fields were not set.
10381ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry         */
10481ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry        @NonNull public WrappedApplicationKey build() {
10581ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry            Preconditions.checkNotNull(mInstance.mAlias);
10681ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry            Preconditions.checkNotNull(mInstance.mEncryptedKeyMaterial);
10781ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry            return mInstance;
10881ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry        }
10981ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    }
11081ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry
111291bd32c9e547a5862d28f3a68ed2f514ccfbd86Robert Berry    private WrappedApplicationKey() { }
11281ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry
11381ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    /**
11481ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry     * Deprecated - consider using Builder.
11581ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry     * @hide
11681ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry     */
11781ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    public WrappedApplicationKey(@NonNull String alias, @NonNull byte[] encryptedKeyMaterial) {
11881ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry        mAlias = Preconditions.checkNotNull(alias);
11981ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry        mEncryptedKeyMaterial = Preconditions.checkNotNull(encryptedKeyMaterial);
12081ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    }
12181ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry
12281ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    /**
12381ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry     * Application-specific alias of the key.
12481ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry     *
12581ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry     * @see java.security.KeyStore.aliases
12681ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry     */
12781ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    public @NonNull String getAlias() {
12881ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry        return mAlias;
12981ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    }
13081ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry
13181ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    /** Key material encrypted by recovery key. */
13281ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    public @NonNull byte[] getEncryptedKeyMaterial() {
13381ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry        return mEncryptedKeyMaterial;
13481ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    }
13581ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry
136291bd32c9e547a5862d28f3a68ed2f514ccfbd86Robert Berry    /**
137c157e21249b01cca18e6712d69c719f245db51a7Robert Berry     * @deprecated AOSP does not associate keys with accounts. This may be done by system app.
1383990ee1c9fcd8f801220edec94e6bef3009809b5Jeff Sharkey     * @removed
139291bd32c9e547a5862d28f3a68ed2f514ccfbd86Robert Berry     */
140291bd32c9e547a5862d28f3a68ed2f514ccfbd86Robert Berry    @Deprecated
1410916e7ca44aba5e6c89d75007da805697fdace9eDmitry Dementyev    public @NonNull byte[] getAccount() {
142745d2c98f9467f1befb7ec3a6c485333d4f1b437Dmitry Dementyev        throw new UnsupportedOperationException();
1430916e7ca44aba5e6c89d75007da805697fdace9eDmitry Dementyev    }
1440916e7ca44aba5e6c89d75007da805697fdace9eDmitry Dementyev
1450916e7ca44aba5e6c89d75007da805697fdace9eDmitry Dementyev    public static final Parcelable.Creator<WrappedApplicationKey> CREATOR =
1460916e7ca44aba5e6c89d75007da805697fdace9eDmitry Dementyev            new Parcelable.Creator<WrappedApplicationKey>() {
14781ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry                public WrappedApplicationKey createFromParcel(Parcel in) {
14881ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry                    return new WrappedApplicationKey(in);
14981ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry                }
15081ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry
15181ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry                public WrappedApplicationKey[] newArray(int length) {
15281ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry                    return new WrappedApplicationKey[length];
15381ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry                }
15481ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry            };
15581ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry
15681ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    @Override
15781ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    public void writeToParcel(Parcel out, int flags) {
15881ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry        out.writeString(mAlias);
15981ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry        out.writeByteArray(mEncryptedKeyMaterial);
16081ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    }
16181ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry
16281ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    /**
16381ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry     * @hide
16481ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry     */
16581ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    protected WrappedApplicationKey(Parcel in) {
16681ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry        mAlias = in.readString();
16781ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry        mEncryptedKeyMaterial = in.createByteArray();
16881ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    }
16981ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry
17081ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    @Override
17181ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    public int describeContents() {
17281ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry        return 0;
17381ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry    }
17481ee34bf957dffe020442e3f0c6c06817397ebf0Robert Berry}
175