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