blob: 9b09dd1ae6ad1d68ee4f1525ea75277079fc6724 [file] [log] [blame]
Bo Zhu14d993d2018-02-03 21:38:48 -08001/*
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 com.android.server.locksettings.recoverablekeystore.storage;
18
19import static com.google.common.truth.Truth.assertThat;
20
21import static java.nio.charset.StandardCharsets.UTF_8;
22
23import org.junit.After;
24import org.junit.Before;
25import org.junit.Test;
26import org.junit.runner.RunWith;
27
28import android.content.ContentValues;
29import android.content.Context;
30import android.database.sqlite.SQLiteDatabase;
31import android.support.test.InstrumentationRegistry;
32import android.support.test.filters.SmallTest;
33import android.support.test.runner.AndroidJUnit4;
34
35import com.android.server.locksettings.recoverablekeystore.storage.RecoverableKeyStoreDbContract.KeysEntry;
36import com.android.server.locksettings.recoverablekeystore.storage.RecoverableKeyStoreDbContract.RecoveryServiceMetadataEntry;
Dmitry Dementyevf34fc7e2018-03-26 17:31:29 -070037import com.android.server.locksettings.recoverablekeystore.storage.RecoverableKeyStoreDbContract.RootOfTrustEntry;
Bo Zhu14d993d2018-02-03 21:38:48 -080038import com.android.server.locksettings.recoverablekeystore.storage.RecoverableKeyStoreDbContract.UserMetadataEntry;
39
40@SmallTest
41@RunWith(AndroidJUnit4.class)
42public class RecoverableKeyStoreDbHelperTest {
43
44 private static final long TEST_USER_ID = 10L;
45 private static final long TEST_UID = 60001L;
46 private static final String TEST_ALIAS = "test-alias";
47 private static final byte[] TEST_NONCE = "test-nonce".getBytes(UTF_8);
48 private static final byte[] TEST_WRAPPED_KEY = "test-wrapped-key".getBytes(UTF_8);
49 private static final long TEST_GENERATION_ID = 13L;
50 private static final long TEST_LAST_SYNCED_AT = 1517990732000L;
51 private static final int TEST_RECOVERY_STATUS = 3;
52 private static final int TEST_PLATFORM_KEY_GENERATION_ID = 11;
53 private static final int TEST_SNAPSHOT_VERSION = 31;
54 private static final int TEST_SHOULD_CREATE_SNAPSHOT = 1;
55 private static final byte[] TEST_PUBLIC_KEY = "test-public-key".getBytes(UTF_8);
56 private static final String TEST_SECRET_TYPES = "test-secret-types";
57 private static final long TEST_COUNTER_ID = -3981205205038476415L;
58 private static final byte[] TEST_SERVER_PARAMS = "test-server-params".getBytes(UTF_8);
Dmitry Dementyevf34fc7e2018-03-26 17:31:29 -070059 private static final String TEST_ROOT_ALIAS = "root_cert_alias";
Bo Zhu14d993d2018-02-03 21:38:48 -080060 private static final byte[] TEST_CERT_PATH = "test-cert-path".getBytes(UTF_8);
61 private static final long TEST_CERT_SERIAL = 1000L;
62
63 private static final String SQL_CREATE_V2_TABLE_KEYS =
64 "CREATE TABLE " + KeysEntry.TABLE_NAME + "( "
65 + KeysEntry._ID + " INTEGER PRIMARY KEY,"
66 + KeysEntry.COLUMN_NAME_USER_ID + " INTEGER,"
67 + KeysEntry.COLUMN_NAME_UID + " INTEGER,"
68 + KeysEntry.COLUMN_NAME_ALIAS + " TEXT,"
69 + KeysEntry.COLUMN_NAME_NONCE + " BLOB,"
70 + KeysEntry.COLUMN_NAME_WRAPPED_KEY + " BLOB,"
71 + KeysEntry.COLUMN_NAME_GENERATION_ID + " INTEGER,"
72 + KeysEntry.COLUMN_NAME_LAST_SYNCED_AT + " INTEGER,"
73 + KeysEntry.COLUMN_NAME_RECOVERY_STATUS + " INTEGER,"
74 + "UNIQUE(" + KeysEntry.COLUMN_NAME_UID + ","
75 + KeysEntry.COLUMN_NAME_ALIAS + "))";
76
77 private static final String SQL_CREATE_V2_TABLE_USER_METADATA =
78 "CREATE TABLE " + UserMetadataEntry.TABLE_NAME + "( "
79 + UserMetadataEntry._ID + " INTEGER PRIMARY KEY,"
80 + UserMetadataEntry.COLUMN_NAME_USER_ID + " INTEGER UNIQUE,"
81 + UserMetadataEntry.COLUMN_NAME_PLATFORM_KEY_GENERATION_ID + " INTEGER)";
82
83 private static final String SQL_CREATE_V2_TABLE_RECOVERY_SERVICE_METADATA =
84 "CREATE TABLE " + RecoveryServiceMetadataEntry.TABLE_NAME + " ("
85 + RecoveryServiceMetadataEntry._ID + " INTEGER PRIMARY KEY,"
86 + RecoveryServiceMetadataEntry.COLUMN_NAME_USER_ID + " INTEGER,"
87 + RecoveryServiceMetadataEntry.COLUMN_NAME_UID + " INTEGER,"
88 + RecoveryServiceMetadataEntry.COLUMN_NAME_SNAPSHOT_VERSION + " INTEGER,"
89 + RecoveryServiceMetadataEntry.COLUMN_NAME_SHOULD_CREATE_SNAPSHOT + " INTEGER,"
90 + RecoveryServiceMetadataEntry.COLUMN_NAME_PUBLIC_KEY + " BLOB,"
91 + RecoveryServiceMetadataEntry.COLUMN_NAME_SECRET_TYPES + " TEXT,"
92 + RecoveryServiceMetadataEntry.COLUMN_NAME_COUNTER_ID + " INTEGER,"
93 + RecoveryServiceMetadataEntry.COLUMN_NAME_SERVER_PARAMS + " BLOB,"
94 + "UNIQUE("
95 + RecoveryServiceMetadataEntry.COLUMN_NAME_USER_ID + ","
96 + RecoveryServiceMetadataEntry.COLUMN_NAME_UID + "))";
97
98 private SQLiteDatabase mDatabase;
99 private RecoverableKeyStoreDbHelper mDatabaseHelper;
100
101 @Before
102 public void setUp() throws Exception {
103 Context context = InstrumentationRegistry.getTargetContext();
104 mDatabaseHelper = new RecoverableKeyStoreDbHelper(context);
105 mDatabase = SQLiteDatabase.create(null);
106 }
107
108 @After
109 public void tearDown() throws Exception {
110 mDatabase.close();
111 }
112
113 private void createV2Tables() throws Exception {
114 mDatabase.execSQL(SQL_CREATE_V2_TABLE_KEYS);
115 mDatabase.execSQL(SQL_CREATE_V2_TABLE_USER_METADATA);
116 mDatabase.execSQL(SQL_CREATE_V2_TABLE_RECOVERY_SERVICE_METADATA);
117 }
118
119 @Test
120 public void onCreate() throws Exception {
121 mDatabaseHelper.onCreate(mDatabase);
122 checkAllColumns();
123 }
124
125 @Test
126 public void onUpgrade_beforeV2() throws Exception {
127 mDatabaseHelper.onUpgrade(mDatabase, /*oldVersion=*/ 1,
128 RecoverableKeyStoreDbHelper.DATABASE_VERSION);
129 checkAllColumns();
130 }
131
132 @Test
133 public void onUpgrade_fromV2() throws Exception {
134 createV2Tables();
135 mDatabaseHelper.onUpgrade(mDatabase, /*oldVersion=*/ 2,
136 RecoverableKeyStoreDbHelper.DATABASE_VERSION);
137 checkAllColumns();
138 }
139
Dmitry Dementyevf34fc7e2018-03-26 17:31:29 -0700140 @Test
141 public void onUpgrade_v2_to_v3_to_v4() throws Exception {
142 createV2Tables();
143
144 assertThat(isRootOfTrustTableAvailable()).isFalse(); // V2 doesn't have the table;
145
146 mDatabaseHelper.onUpgrade(mDatabase, /*oldVersion=*/ 2, /*newVersion=*/ 3);
147
148 assertThat(isRootOfTrustTableAvailable()).isFalse(); // V3 doesn't have the table;
149
150 mDatabaseHelper.onUpgrade(mDatabase, /*oldVersion=*/ 3,
151 RecoverableKeyStoreDbHelper.DATABASE_VERSION);
152 checkAllColumns();
153 }
154
155 private boolean isRootOfTrustTableAvailable() {
156 ContentValues values = new ContentValues();
157 values.put(RootOfTrustEntry.COLUMN_NAME_USER_ID, TEST_USER_ID);
158 values.put(RootOfTrustEntry.COLUMN_NAME_UID, TEST_UID);
159 values.put(RootOfTrustEntry.COLUMN_NAME_ROOT_ALIAS, TEST_ROOT_ALIAS);
160 values.put(RootOfTrustEntry.COLUMN_NAME_CERT_PATH, TEST_CERT_PATH);
161 values.put(RootOfTrustEntry.COLUMN_NAME_CERT_SERIAL, TEST_CERT_SERIAL);
162 return mDatabase.insert(RootOfTrustEntry.TABLE_NAME, /*nullColumnHack=*/ null, values)
163 > -1;
164 }
165
Bo Zhu14d993d2018-02-03 21:38:48 -0800166 private void checkAllColumns() throws Exception {
167 // Check the table containing encrypted application keys
168 ContentValues values = new ContentValues();
169 values.put(KeysEntry.COLUMN_NAME_USER_ID, TEST_USER_ID);
170 values.put(KeysEntry.COLUMN_NAME_UID, TEST_UID);
171 values.put(KeysEntry.COLUMN_NAME_ALIAS, TEST_ALIAS);
172 values.put(KeysEntry.COLUMN_NAME_NONCE, TEST_NONCE);
173 values.put(KeysEntry.COLUMN_NAME_WRAPPED_KEY, TEST_WRAPPED_KEY);
174 values.put(KeysEntry.COLUMN_NAME_GENERATION_ID, TEST_GENERATION_ID);
175 values.put(KeysEntry.COLUMN_NAME_LAST_SYNCED_AT, TEST_LAST_SYNCED_AT);
176 values.put(KeysEntry.COLUMN_NAME_RECOVERY_STATUS, TEST_RECOVERY_STATUS);
177 assertThat(mDatabase.insert(KeysEntry.TABLE_NAME, /*nullColumnHack=*/ null, values))
178 .isGreaterThan(-1L);
179
180 // Check the table about user metadata
181 values = new ContentValues();
182 values.put(UserMetadataEntry.COLUMN_NAME_USER_ID, TEST_USER_ID);
183 values.put(UserMetadataEntry.COLUMN_NAME_PLATFORM_KEY_GENERATION_ID,
184 TEST_PLATFORM_KEY_GENERATION_ID);
185 assertThat(mDatabase.insert(UserMetadataEntry.TABLE_NAME, /*nullColumnHack=*/ null, values))
186 .isGreaterThan(-1L);
187
188 // Check the table about recovery service metadata
189 values = new ContentValues();
190 values.put(RecoveryServiceMetadataEntry.COLUMN_NAME_USER_ID, TEST_USER_ID);
191 values.put(RecoveryServiceMetadataEntry.COLUMN_NAME_UID, TEST_UID);
192 values.put(RecoveryServiceMetadataEntry.COLUMN_NAME_SNAPSHOT_VERSION,
193 TEST_SNAPSHOT_VERSION);
194 values.put(RecoveryServiceMetadataEntry.COLUMN_NAME_SHOULD_CREATE_SNAPSHOT,
195 TEST_SHOULD_CREATE_SNAPSHOT);
Dmitry Dementyevf34fc7e2018-03-26 17:31:29 -0700196 values.put(RecoveryServiceMetadataEntry.COLUMN_NAME_ACTIVE_ROOT_OF_TRUST, TEST_ROOT_ALIAS);
Bo Zhu14d993d2018-02-03 21:38:48 -0800197 values.put(RecoveryServiceMetadataEntry.COLUMN_NAME_PUBLIC_KEY, TEST_PUBLIC_KEY);
198 values.put(RecoveryServiceMetadataEntry.COLUMN_NAME_SECRET_TYPES, TEST_SECRET_TYPES);
199 values.put(RecoveryServiceMetadataEntry.COLUMN_NAME_COUNTER_ID, TEST_COUNTER_ID);
200 values.put(RecoveryServiceMetadataEntry.COLUMN_NAME_SERVER_PARAMS, TEST_SERVER_PARAMS);
201 values.put(RecoveryServiceMetadataEntry.COLUMN_NAME_CERT_PATH, TEST_CERT_PATH);
202 values.put(RecoveryServiceMetadataEntry.COLUMN_NAME_CERT_SERIAL, TEST_CERT_SERIAL);
203 assertThat(
204 mDatabase.insert(RecoveryServiceMetadataEntry.TABLE_NAME, /*nullColumnHack=*/ null,
205 values))
206 .isGreaterThan(-1L);
Dmitry Dementyevf34fc7e2018-03-26 17:31:29 -0700207
208 // Check the table about recovery service and root of trust data introduced in V4
209 assertThat(isRootOfTrustTableAvailable()).isTrue();
Bo Zhu14d993d2018-02-03 21:38:48 -0800210 }
211}