blob: b3d949395d5c73d1508fca74e6dc2a38875724eb [file] [log] [blame]
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +00001/*
2 * Copyright (C) 2019 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.integrity.serializer;
18
Khaled Abdelmohsen4524c422019-12-02 17:43:31 +000019import static com.android.server.integrity.model.ComponentBitSize.ATOMIC_FORMULA_START;
20import static com.android.server.integrity.model.ComponentBitSize.COMPOUND_FORMULA_END;
21import static com.android.server.integrity.model.ComponentBitSize.COMPOUND_FORMULA_START;
22import static com.android.server.integrity.model.ComponentBitSize.CONNECTOR_BITS;
23import static com.android.server.integrity.model.ComponentBitSize.DEFAULT_FORMAT_VERSION;
24import static com.android.server.integrity.model.ComponentBitSize.EFFECT_BITS;
25import static com.android.server.integrity.model.ComponentBitSize.FORMAT_VERSION_BITS;
26import static com.android.server.integrity.model.ComponentBitSize.KEY_BITS;
27import static com.android.server.integrity.model.ComponentBitSize.OPERATOR_BITS;
28import static com.android.server.integrity.model.ComponentBitSize.SEPARATOR_BITS;
29import static com.android.server.integrity.model.ComponentBitSize.VALUE_SIZE_BITS;
Omer Nebil Yaveroglu4f5ceae2020-01-07 14:06:57 +000030import static com.android.server.integrity.model.IndexingFileConstants.END_INDEXING_KEY;
31import static com.android.server.integrity.model.IndexingFileConstants.INDEXING_BLOCK_SIZE;
32import static com.android.server.integrity.model.IndexingFileConstants.START_INDEXING_KEY;
Omer Nebil Yaveroglu35e8f362020-01-17 10:54:10 +000033import static com.android.server.integrity.serializer.RuleBinarySerializer.INDEXED_RULE_SIZE_LIMIT;
34import static com.android.server.integrity.serializer.RuleBinarySerializer.NONINDEXED_RULE_SIZE_LIMIT;
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +000035import static com.android.server.integrity.utils.TestUtils.getBits;
36import static com.android.server.integrity.utils.TestUtils.getBytes;
37import static com.android.server.integrity.utils.TestUtils.getValueBits;
38import static com.android.server.testutils.TestUtils.assertExpectException;
39
40import static com.google.common.truth.Truth.assertThat;
41
42import android.content.integrity.AppInstallMetadata;
43import android.content.integrity.AtomicFormula;
44import android.content.integrity.CompoundFormula;
Omer Nebil Yaveroglu15395f52020-01-22 12:14:44 +000045import android.content.integrity.IntegrityFormula;
46import android.content.integrity.IntegrityUtils;
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +000047import android.content.integrity.Rule;
48
49import androidx.annotation.NonNull;
50
51import org.junit.Test;
52import org.junit.runner.RunWith;
53import org.junit.runners.JUnit4;
54
55import java.io.ByteArrayOutputStream;
Khaled Abdelmohsen117223a2019-12-23 18:32:11 +000056import java.nio.charset.StandardCharsets;
Omer Nebil Yaverogluf8047642019-12-20 14:57:15 +000057import java.util.ArrayList;
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +000058import java.util.Arrays;
59import java.util.Collections;
Omer Nebil Yaverogluf8047642019-12-20 14:57:15 +000060import java.util.List;
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +000061import java.util.Optional;
62
63@RunWith(JUnit4.class)
64public class RuleBinarySerializerTest {
65
Omer Nebil Yaverogluf8047642019-12-20 14:57:15 +000066 private static final String SAMPLE_INSTALLER_NAME = "com.test.installer";
67 private static final String SAMPLE_INSTALLER_CERT = "installer_cert";
68
Khaled Abdelmohsen4524c422019-12-02 17:43:31 +000069 private static final String COMPOUND_FORMULA_START_BITS =
70 getBits(COMPOUND_FORMULA_START, SEPARATOR_BITS);
71 private static final String COMPOUND_FORMULA_END_BITS =
72 getBits(COMPOUND_FORMULA_END, SEPARATOR_BITS);
73 private static final String ATOMIC_FORMULA_START_BITS =
74 getBits(ATOMIC_FORMULA_START, SEPARATOR_BITS);
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +000075
Khaled Abdelmohsen4524c422019-12-02 17:43:31 +000076 private static final String NOT = getBits(CompoundFormula.NOT, CONNECTOR_BITS);
77 private static final String AND = getBits(CompoundFormula.AND, CONNECTOR_BITS);
78 private static final String OR = getBits(CompoundFormula.OR, CONNECTOR_BITS);
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +000079
Khaled Abdelmohsen4524c422019-12-02 17:43:31 +000080 private static final String PACKAGE_NAME = getBits(AtomicFormula.PACKAGE_NAME, KEY_BITS);
81 private static final String APP_CERTIFICATE = getBits(AtomicFormula.APP_CERTIFICATE, KEY_BITS);
Omer Nebil Yaverogluf8047642019-12-20 14:57:15 +000082 private static final String INSTALLER_NAME = getBits(AtomicFormula.INSTALLER_NAME, KEY_BITS);
83 private static final String INSTALLER_CERTIFICATE =
84 getBits(AtomicFormula.INSTALLER_CERTIFICATE, KEY_BITS);
Khaled Abdelmohsen4524c422019-12-02 17:43:31 +000085 private static final String VERSION_CODE = getBits(AtomicFormula.VERSION_CODE, KEY_BITS);
86 private static final String PRE_INSTALLED = getBits(AtomicFormula.PRE_INSTALLED, KEY_BITS);
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +000087
Khaled Abdelmohsen4524c422019-12-02 17:43:31 +000088 private static final String EQ = getBits(AtomicFormula.EQ, OPERATOR_BITS);
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +000089
90 private static final String IS_NOT_HASHED = "0";
Khaled Abdelmohsen117223a2019-12-23 18:32:11 +000091 private static final String IS_HASHED = "1";
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +000092
Khaled Abdelmohsen4524c422019-12-02 17:43:31 +000093 private static final String DENY = getBits(Rule.DENY, EFFECT_BITS);
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +000094
95 private static final String START_BIT = "1";
96 private static final String END_BIT = "1";
97
Khaled Abdelmohsen4524c422019-12-02 17:43:31 +000098 private static final byte[] DEFAULT_FORMAT_VERSION_BYTES =
99 getBytes(getBits(DEFAULT_FORMAT_VERSION, FORMAT_VERSION_BITS));
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000100
Omer Nebil Yaveroglu2935a212020-01-03 14:33:51 +0000101 private static final String SERIALIZED_START_INDEXING_KEY =
102 IS_NOT_HASHED
103 + getBits(START_INDEXING_KEY.length(), VALUE_SIZE_BITS)
104 + getValueBits(START_INDEXING_KEY);
105 private static final String SERIALIZED_END_INDEXING_KEY =
106 IS_NOT_HASHED
107 + getBits(END_INDEXING_KEY.length(), VALUE_SIZE_BITS)
108 + getValueBits(END_INDEXING_KEY);
109
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000110 @Test
Omer Nebil Yaverogluf8047642019-12-20 14:57:15 +0000111 public void testBinaryString_serializeNullRules() {
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000112 RuleSerializer binarySerializer = new RuleBinarySerializer();
113
114 assertExpectException(
115 RuleSerializeException.class,
Omer Nebil Yaveroglu35e8f362020-01-17 10:54:10 +0000116 /* expectedExceptionMessageRegex= */ "Null rules cannot be serialized.",
Khaled Abdelmohsen117223a2019-12-23 18:32:11 +0000117 () -> binarySerializer.serialize(null, /* formatVersion= */ Optional.empty()));
Omer Nebil Yaverogluf8047642019-12-20 14:57:15 +0000118 }
119
120 @Test
121 public void testBinaryString_emptyRules() throws Exception {
Omer Nebil Yaveroglu2935a212020-01-03 14:33:51 +0000122 ByteArrayOutputStream ruleOutputStream = new ByteArrayOutputStream();
123 ByteArrayOutputStream indexingOutputStream = new ByteArrayOutputStream();
Omer Nebil Yaverogluf8047642019-12-20 14:57:15 +0000124 RuleSerializer binarySerializer = new RuleBinarySerializer();
Omer Nebil Yaverogluf8047642019-12-20 14:57:15 +0000125
Omer Nebil Yaveroglu2935a212020-01-03 14:33:51 +0000126 binarySerializer.serialize(
127 Collections.emptyList(),
128 /* formatVersion= */ Optional.empty(),
129 ruleOutputStream,
130 indexingOutputStream);
131
132 ByteArrayOutputStream expectedRuleOutputStream = new ByteArrayOutputStream();
133 expectedRuleOutputStream.write(DEFAULT_FORMAT_VERSION_BYTES);
134 assertThat(ruleOutputStream.toByteArray())
135 .isEqualTo(expectedRuleOutputStream.toByteArray());
136
137 ByteArrayOutputStream expectedIndexingOutputStream = new ByteArrayOutputStream();
Omer Nebil Yaveroglu8d46f342020-01-13 15:28:11 +0000138 String serializedIndexingBytes =
139 SERIALIZED_START_INDEXING_KEY
140 + getBits(DEFAULT_FORMAT_VERSION_BYTES.length, /* numOfBits= */ 32)
141 + SERIALIZED_END_INDEXING_KEY
Song Pane5d60742020-01-10 17:58:00 +0000142 + getBits(DEFAULT_FORMAT_VERSION_BYTES.length, /* numOfBits= */ 32);
Omer Nebil Yaveroglu2935a212020-01-03 14:33:51 +0000143 byte[] expectedIndexingBytes =
Song Pane5d60742020-01-10 17:58:00 +0000144 getBytes(
145 serializedIndexingBytes
146 + serializedIndexingBytes
147 + serializedIndexingBytes);
Omer Nebil Yaveroglu2935a212020-01-03 14:33:51 +0000148 expectedIndexingOutputStream.write(expectedIndexingBytes);
149 assertThat(indexingOutputStream.toByteArray())
150 .isEqualTo(expectedIndexingOutputStream.toByteArray());
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000151 }
152
153 @Test
154 public void testBinaryStream_serializeValidCompoundFormula() throws Exception {
155 String packageName = "com.test.app";
156 Rule rule =
157 new Rule(
158 new CompoundFormula(
159 CompoundFormula.NOT,
160 Collections.singletonList(
161 new AtomicFormula.StringAtomicFormula(
162 AtomicFormula.PACKAGE_NAME,
163 packageName,
164 /* isHashedValue= */ false))),
165 Rule.DENY);
Omer Nebil Yaveroglu2935a212020-01-03 14:33:51 +0000166
167 ByteArrayOutputStream ruleOutputStream = new ByteArrayOutputStream();
168 ByteArrayOutputStream indexingOutputStream = new ByteArrayOutputStream();
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000169 RuleSerializer binarySerializer = new RuleBinarySerializer();
Omer Nebil Yaveroglu2935a212020-01-03 14:33:51 +0000170 binarySerializer.serialize(
171 Collections.singletonList(rule),
172 /* formatVersion= */ Optional.empty(),
173 ruleOutputStream,
174 indexingOutputStream);
175
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000176 String expectedBits =
177 START_BIT
Khaled Abdelmohsen4524c422019-12-02 17:43:31 +0000178 + COMPOUND_FORMULA_START_BITS
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000179 + NOT
Khaled Abdelmohsen4524c422019-12-02 17:43:31 +0000180 + ATOMIC_FORMULA_START_BITS
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000181 + PACKAGE_NAME
182 + EQ
183 + IS_NOT_HASHED
Khaled Abdelmohsen4524c422019-12-02 17:43:31 +0000184 + getBits(packageName.length(), VALUE_SIZE_BITS)
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000185 + getValueBits(packageName)
Khaled Abdelmohsen4524c422019-12-02 17:43:31 +0000186 + COMPOUND_FORMULA_END_BITS
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000187 + DENY
188 + END_BIT;
Omer Nebil Yaveroglu2935a212020-01-03 14:33:51 +0000189 ByteArrayOutputStream expectedRuleOutputStream = new ByteArrayOutputStream();
190 expectedRuleOutputStream.write(DEFAULT_FORMAT_VERSION_BYTES);
191 expectedRuleOutputStream.write(getBytes(expectedBits));
192 assertThat(ruleOutputStream.toByteArray())
193 .isEqualTo(expectedRuleOutputStream.toByteArray());
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000194
Omer Nebil Yaveroglu2935a212020-01-03 14:33:51 +0000195 ByteArrayOutputStream expectedIndexingOutputStream = new ByteArrayOutputStream();
196 String expectedIndexingBitsForIndexed =
197 SERIALIZED_START_INDEXING_KEY
198 + getBits(DEFAULT_FORMAT_VERSION_BYTES.length, /* numOfBits= */ 32)
199 + SERIALIZED_END_INDEXING_KEY
200 + getBits(DEFAULT_FORMAT_VERSION_BYTES.length, /* numOfBits= */ 32);
Omer Nebil Yaveroglu2935a212020-01-03 14:33:51 +0000201 String expectedIndexingBitsForUnindexed =
202 SERIALIZED_START_INDEXING_KEY
203 + getBits(DEFAULT_FORMAT_VERSION_BYTES.length, /* numOfBits= */ 32)
204 + SERIALIZED_END_INDEXING_KEY
Song Pane5d60742020-01-10 17:58:00 +0000205 + getBits(
Omer Nebil Yaveroglu35e8f362020-01-17 10:54:10 +0000206 DEFAULT_FORMAT_VERSION_BYTES.length + getBytes(expectedBits).length,
207 /* numOfBits= */ 32);
Song Pane5d60742020-01-10 17:58:00 +0000208 expectedIndexingOutputStream.write(
209 getBytes(
210 expectedIndexingBitsForIndexed
211 + expectedIndexingBitsForIndexed
212 + expectedIndexingBitsForUnindexed));
Omer Nebil Yaveroglu8d46f342020-01-13 15:28:11 +0000213
Omer Nebil Yaveroglu2935a212020-01-03 14:33:51 +0000214 assertThat(indexingOutputStream.toByteArray())
215 .isEqualTo(expectedIndexingOutputStream.toByteArray());
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000216 }
217
218 @Test
219 public void testBinaryString_serializeValidCompoundFormula_notConnector() throws Exception {
220 String packageName = "com.test.app";
221 Rule rule =
222 new Rule(
223 new CompoundFormula(
224 CompoundFormula.NOT,
225 Collections.singletonList(
226 new AtomicFormula.StringAtomicFormula(
227 AtomicFormula.PACKAGE_NAME,
228 packageName,
229 /* isHashedValue= */ false))),
230 Rule.DENY);
231 RuleSerializer binarySerializer = new RuleBinarySerializer();
232 String expectedBits =
233 START_BIT
Khaled Abdelmohsen4524c422019-12-02 17:43:31 +0000234 + COMPOUND_FORMULA_START_BITS
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000235 + NOT
Khaled Abdelmohsen4524c422019-12-02 17:43:31 +0000236 + ATOMIC_FORMULA_START_BITS
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000237 + PACKAGE_NAME
238 + EQ
239 + IS_NOT_HASHED
Khaled Abdelmohsen4524c422019-12-02 17:43:31 +0000240 + getBits(packageName.length(), VALUE_SIZE_BITS)
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000241 + getValueBits(packageName)
Khaled Abdelmohsen4524c422019-12-02 17:43:31 +0000242 + COMPOUND_FORMULA_END_BITS
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000243 + DENY
244 + END_BIT;
245 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
Khaled Abdelmohsen4524c422019-12-02 17:43:31 +0000246 byteArrayOutputStream.write(DEFAULT_FORMAT_VERSION_BYTES);
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000247 byteArrayOutputStream.write(getBytes(expectedBits));
248 byte[] expectedRules = byteArrayOutputStream.toByteArray();
249
250 byte[] actualRules =
251 binarySerializer.serialize(
252 Collections.singletonList(rule), /* formatVersion= */ Optional.empty());
253
254 assertThat(actualRules).isEqualTo(expectedRules);
255 }
256
257 @Test
258 public void testBinaryString_serializeValidCompoundFormula_andConnector() throws Exception {
259 String packageName = "com.test.app";
260 String appCertificate = "test_cert";
261 Rule rule =
262 new Rule(
263 new CompoundFormula(
264 CompoundFormula.AND,
265 Arrays.asList(
266 new AtomicFormula.StringAtomicFormula(
267 AtomicFormula.PACKAGE_NAME,
268 packageName,
269 /* isHashedValue= */ false),
270 new AtomicFormula.StringAtomicFormula(
271 AtomicFormula.APP_CERTIFICATE,
272 appCertificate,
273 /* isHashedValue= */ false))),
274 Rule.DENY);
275 RuleSerializer binarySerializer = new RuleBinarySerializer();
276 String expectedBits =
277 START_BIT
Khaled Abdelmohsen4524c422019-12-02 17:43:31 +0000278 + COMPOUND_FORMULA_START_BITS
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000279 + AND
Khaled Abdelmohsen4524c422019-12-02 17:43:31 +0000280 + ATOMIC_FORMULA_START_BITS
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000281 + PACKAGE_NAME
282 + EQ
283 + IS_NOT_HASHED
Khaled Abdelmohsen4524c422019-12-02 17:43:31 +0000284 + getBits(packageName.length(), VALUE_SIZE_BITS)
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000285 + getValueBits(packageName)
Khaled Abdelmohsen4524c422019-12-02 17:43:31 +0000286 + ATOMIC_FORMULA_START_BITS
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000287 + APP_CERTIFICATE
288 + EQ
289 + IS_NOT_HASHED
Khaled Abdelmohsen4524c422019-12-02 17:43:31 +0000290 + getBits(appCertificate.length(), VALUE_SIZE_BITS)
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000291 + getValueBits(appCertificate)
Khaled Abdelmohsen4524c422019-12-02 17:43:31 +0000292 + COMPOUND_FORMULA_END_BITS
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000293 + DENY
294 + END_BIT;
295 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
Khaled Abdelmohsen4524c422019-12-02 17:43:31 +0000296 byteArrayOutputStream.write(DEFAULT_FORMAT_VERSION_BYTES);
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000297 byteArrayOutputStream.write(getBytes(expectedBits));
298 byte[] expectedRules = byteArrayOutputStream.toByteArray();
299
300 byte[] actualRules =
301 binarySerializer.serialize(
302 Collections.singletonList(rule), /* formatVersion= */ Optional.empty());
303
304 assertThat(actualRules).isEqualTo(expectedRules);
305 }
306
307 @Test
308 public void testBinaryString_serializeValidCompoundFormula_orConnector() throws Exception {
309 String packageName = "com.test.app";
310 String appCertificate = "test_cert";
311 Rule rule =
312 new Rule(
313 new CompoundFormula(
314 CompoundFormula.OR,
315 Arrays.asList(
316 new AtomicFormula.StringAtomicFormula(
317 AtomicFormula.PACKAGE_NAME,
318 packageName,
319 /* isHashedValue= */ false),
320 new AtomicFormula.StringAtomicFormula(
321 AtomicFormula.APP_CERTIFICATE,
322 appCertificate,
323 /* isHashedValue= */ false))),
324 Rule.DENY);
325 RuleSerializer binarySerializer = new RuleBinarySerializer();
326 String expectedBits =
327 START_BIT
Khaled Abdelmohsen4524c422019-12-02 17:43:31 +0000328 + COMPOUND_FORMULA_START_BITS
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000329 + OR
Khaled Abdelmohsen4524c422019-12-02 17:43:31 +0000330 + ATOMIC_FORMULA_START_BITS
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000331 + PACKAGE_NAME
332 + EQ
333 + IS_NOT_HASHED
Khaled Abdelmohsen4524c422019-12-02 17:43:31 +0000334 + getBits(packageName.length(), VALUE_SIZE_BITS)
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000335 + getValueBits(packageName)
Khaled Abdelmohsen4524c422019-12-02 17:43:31 +0000336 + ATOMIC_FORMULA_START_BITS
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000337 + APP_CERTIFICATE
338 + EQ
339 + IS_NOT_HASHED
Khaled Abdelmohsen4524c422019-12-02 17:43:31 +0000340 + getBits(appCertificate.length(), VALUE_SIZE_BITS)
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000341 + getValueBits(appCertificate)
Khaled Abdelmohsen4524c422019-12-02 17:43:31 +0000342 + COMPOUND_FORMULA_END_BITS
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000343 + DENY
344 + END_BIT;
345 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
Khaled Abdelmohsen4524c422019-12-02 17:43:31 +0000346 byteArrayOutputStream.write(DEFAULT_FORMAT_VERSION_BYTES);
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000347 byteArrayOutputStream.write(getBytes(expectedBits));
348 byte[] expectedRules = byteArrayOutputStream.toByteArray();
349
350 byte[] actualRules =
351 binarySerializer.serialize(
352 Collections.singletonList(rule), /* formatVersion= */ Optional.empty());
353
354 assertThat(actualRules).isEqualTo(expectedRules);
355 }
356
357 @Test
358 public void testBinaryString_serializeValidAtomicFormula_stringValue() throws Exception {
359 String packageName = "com.test.app";
360 Rule rule =
361 new Rule(
362 new AtomicFormula.StringAtomicFormula(
363 AtomicFormula.PACKAGE_NAME,
364 packageName,
365 /* isHashedValue= */ false),
366 Rule.DENY);
367 RuleSerializer binarySerializer = new RuleBinarySerializer();
368 String expectedBits =
369 START_BIT
Khaled Abdelmohsen4524c422019-12-02 17:43:31 +0000370 + ATOMIC_FORMULA_START_BITS
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000371 + PACKAGE_NAME
372 + EQ
373 + IS_NOT_HASHED
Khaled Abdelmohsen4524c422019-12-02 17:43:31 +0000374 + getBits(packageName.length(), VALUE_SIZE_BITS)
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000375 + getValueBits(packageName)
376 + DENY
377 + END_BIT;
378 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
Khaled Abdelmohsen4524c422019-12-02 17:43:31 +0000379 byteArrayOutputStream.write(DEFAULT_FORMAT_VERSION_BYTES);
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000380 byteArrayOutputStream.write(getBytes(expectedBits));
381 byte[] expectedRules = byteArrayOutputStream.toByteArray();
382
383 byte[] actualRules =
384 binarySerializer.serialize(
385 Collections.singletonList(rule), /* formatVersion= */ Optional.empty());
386
387 assertThat(actualRules).isEqualTo(expectedRules);
388 }
389
390 @Test
Khaled Abdelmohsen117223a2019-12-23 18:32:11 +0000391 public void testBinaryString_serializeValidAtomicFormula_hashedValue() throws Exception {
Khaled Abdelmohsen88273f12019-12-31 14:21:32 +0000392 String appCertificate = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
Khaled Abdelmohsen117223a2019-12-23 18:32:11 +0000393 Rule rule =
394 new Rule(
395 new AtomicFormula.StringAtomicFormula(
396 AtomicFormula.APP_CERTIFICATE,
397 IntegrityUtils.getHexDigest(
398 appCertificate.getBytes(StandardCharsets.UTF_8)),
399 /* isHashedValue= */ true),
400 Rule.DENY);
401 RuleSerializer binarySerializer = new RuleBinarySerializer();
402 String expectedBits =
403 START_BIT
404 + ATOMIC_FORMULA_START_BITS
405 + APP_CERTIFICATE
406 + EQ
407 + IS_HASHED
408 + getBits(appCertificate.length(), VALUE_SIZE_BITS)
409 + getValueBits(appCertificate)
410 + DENY
411 + END_BIT;
412 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
413 byteArrayOutputStream.write(DEFAULT_FORMAT_VERSION_BYTES);
414 byteArrayOutputStream.write(getBytes(expectedBits));
415 byte[] expectedRules = byteArrayOutputStream.toByteArray();
416
417 byte[] actualRules =
418 binarySerializer.serialize(
419 Collections.singletonList(rule), /* formatVersion= */ Optional.empty());
420
421 assertThat(actualRules).isEqualTo(expectedRules);
422 }
423
424 @Test
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000425 public void testBinaryString_serializeValidAtomicFormula_integerValue() throws Exception {
Omer Nebil Yaveroglu15395f52020-01-22 12:14:44 +0000426 long versionCode = 1;
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000427 Rule rule =
428 new Rule(
Omer Nebil Yaveroglu15395f52020-01-22 12:14:44 +0000429 new AtomicFormula.LongAtomicFormula(
430 AtomicFormula.VERSION_CODE, AtomicFormula.EQ,
431 versionCode),
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000432 Rule.DENY);
433 RuleSerializer binarySerializer = new RuleBinarySerializer();
434 String expectedBits =
435 START_BIT
Khaled Abdelmohsen4524c422019-12-02 17:43:31 +0000436 + ATOMIC_FORMULA_START_BITS
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000437 + VERSION_CODE
438 + EQ
Omer Nebil Yaveroglu15395f52020-01-22 12:14:44 +0000439 + getBits(versionCode, /* numOfBits= */ 64)
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000440 + DENY
441 + END_BIT;
442 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
Khaled Abdelmohsen4524c422019-12-02 17:43:31 +0000443 byteArrayOutputStream.write(DEFAULT_FORMAT_VERSION_BYTES);
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000444 byteArrayOutputStream.write(getBytes(expectedBits));
445 byte[] expectedRules = byteArrayOutputStream.toByteArray();
446
447 byte[] actualRules =
448 binarySerializer.serialize(
449 Collections.singletonList(rule), /* formatVersion= */ Optional.empty());
450
451 assertThat(actualRules).isEqualTo(expectedRules);
452 }
453
454 @Test
455 public void testBinaryString_serializeValidAtomicFormula_booleanValue() throws Exception {
456 String preInstalled = "1";
457 Rule rule =
458 new Rule(
Omer Nebil Yaveroglu15395f52020-01-22 12:14:44 +0000459 new AtomicFormula.BooleanAtomicFormula(
460 AtomicFormula.PRE_INSTALLED, true),
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000461 Rule.DENY);
462 RuleSerializer binarySerializer = new RuleBinarySerializer();
463 String expectedBits =
464 START_BIT
Khaled Abdelmohsen4524c422019-12-02 17:43:31 +0000465 + ATOMIC_FORMULA_START_BITS
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000466 + PRE_INSTALLED
467 + EQ
Khaled Abdelmohsen117223a2019-12-23 18:32:11 +0000468 + preInstalled
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000469 + DENY
470 + END_BIT;
471 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
Khaled Abdelmohsen4524c422019-12-02 17:43:31 +0000472 byteArrayOutputStream.write(DEFAULT_FORMAT_VERSION_BYTES);
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000473 byteArrayOutputStream.write(getBytes(expectedBits));
474 byte[] expectedRules = byteArrayOutputStream.toByteArray();
475
476 byte[] actualRules =
477 binarySerializer.serialize(
478 Collections.singletonList(rule), /* formatVersion= */ Optional.empty());
479
480 assertThat(actualRules).isEqualTo(expectedRules);
481 }
482
483 @Test
484 public void testBinaryString_serializeInvalidFormulaType() throws Exception {
Omer Nebil Yaveroglu15395f52020-01-22 12:14:44 +0000485 IntegrityFormula invalidFormula = getInvalidFormula();
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000486 Rule rule = new Rule(invalidFormula, Rule.DENY);
487 RuleSerializer binarySerializer = new RuleBinarySerializer();
488
489 assertExpectException(
490 RuleSerializeException.class,
Omer Nebil Yaverogluf8047642019-12-20 14:57:15 +0000491 /* expectedExceptionMessageRegex= */ "Malformed rule identified.",
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000492 () ->
493 binarySerializer.serialize(
494 Collections.singletonList(rule),
495 /* formatVersion= */ Optional.empty()));
496 }
497
498 @Test
499 public void testBinaryString_serializeFormatVersion() throws Exception {
500 int formatVersion = 1;
501 RuleSerializer binarySerializer = new RuleBinarySerializer();
Khaled Abdelmohsen4524c422019-12-02 17:43:31 +0000502 String expectedBits = getBits(formatVersion, FORMAT_VERSION_BITS);
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000503 byte[] expectedRules = getBytes(expectedBits);
504
505 byte[] actualRules =
506 binarySerializer.serialize(
507 Collections.emptyList(), /* formatVersion= */ Optional.of(formatVersion));
508
509 assertThat(actualRules).isEqualTo(expectedRules);
510 }
511
Omer Nebil Yaverogluf8047642019-12-20 14:57:15 +0000512 @Test
Omer Nebil Yaveroglu2935a212020-01-03 14:33:51 +0000513 public void testBinaryString_verifyManyRulesAreIndexedCorrectly() throws Exception {
514 int ruleCount = 225;
515 String packagePrefix = "package.name.";
516 String appCertificatePrefix = "app.cert.";
517 String installerNamePrefix = "installer.";
Omer Nebil Yaverogluf8047642019-12-20 14:57:15 +0000518
Omer Nebil Yaveroglu2935a212020-01-03 14:33:51 +0000519 // Create the rule set with 225 package name based rules, 225 app certificate indexed rules,
520 // and 225 non-indexed rules..
Omer Nebil Yaverogluf8047642019-12-20 14:57:15 +0000521 List<Rule> ruleList = new ArrayList();
Omer Nebil Yaveroglu2935a212020-01-03 14:33:51 +0000522 for (int count = 0; count < ruleCount; count++) {
Song Pane5d60742020-01-10 17:58:00 +0000523 ruleList.add(
524 getRuleWithPackageNameAndSampleInstallerName(
525 String.format("%s%04d", packagePrefix, count)));
Omer Nebil Yaveroglu2935a212020-01-03 14:33:51 +0000526 }
527 for (int count = 0; count < ruleCount; count++) {
Song Pane5d60742020-01-10 17:58:00 +0000528 ruleList.add(
529 getRuleWithAppCertificateAndSampleInstallerName(
530 String.format("%s%04d", appCertificatePrefix, count)));
Omer Nebil Yaveroglu2935a212020-01-03 14:33:51 +0000531 }
532 for (int count = 0; count < ruleCount; count++) {
Song Pane5d60742020-01-10 17:58:00 +0000533 ruleList.add(
534 getNonIndexedRuleWithInstallerName(
535 String.format("%s%04d", installerNamePrefix, count)));
Omer Nebil Yaveroglu2935a212020-01-03 14:33:51 +0000536 }
Omer Nebil Yaverogluf8047642019-12-20 14:57:15 +0000537
Omer Nebil Yaveroglu2935a212020-01-03 14:33:51 +0000538 // Serialize the rules.
539 ByteArrayOutputStream ruleOutputStream = new ByteArrayOutputStream();
540 ByteArrayOutputStream indexingOutputStream = new ByteArrayOutputStream();
541 RuleSerializer binarySerializer = new RuleBinarySerializer();
542 binarySerializer.serialize(
543 ruleList,
544 /* formatVersion= */ Optional.empty(),
545 ruleOutputStream,
546 indexingOutputStream);
Omer Nebil Yaverogluf8047642019-12-20 14:57:15 +0000547
Omer Nebil Yaveroglu2935a212020-01-03 14:33:51 +0000548 // Verify the rules file and index files.
549 ByteArrayOutputStream expectedOrderedRuleOutputStream = new ByteArrayOutputStream();
550 ByteArrayOutputStream expectedIndexingOutputStream = new ByteArrayOutputStream();
551
552 expectedOrderedRuleOutputStream.write(DEFAULT_FORMAT_VERSION_BYTES);
553 int totalBytesWritten = DEFAULT_FORMAT_VERSION_BYTES.length;
554
555 String expectedIndexingBytesForPackageNameIndexed =
Song Pane5d60742020-01-10 17:58:00 +0000556 SERIALIZED_START_INDEXING_KEY + getBits(totalBytesWritten, /* numOfBits= */ 32);
Omer Nebil Yaveroglu2935a212020-01-03 14:33:51 +0000557 for (int count = 0; count < ruleCount; count++) {
558 String packageName = String.format("%s%04d", packagePrefix, count);
559 if (count > 0 && count % INDEXING_BLOCK_SIZE == 0) {
560 expectedIndexingBytesForPackageNameIndexed +=
561 IS_NOT_HASHED
562 + getBits(packageName.length(), VALUE_SIZE_BITS)
563 + getValueBits(packageName)
564 + getBits(totalBytesWritten, /* numOfBits= */ 32);
565 }
566
567 byte[] bytesForPackage =
Song Pane5d60742020-01-10 17:58:00 +0000568 getBytes(
569 getSerializedCompoundRuleWithPackageNameAndSampleInstallerName(
570 packageName));
Omer Nebil Yaveroglu2935a212020-01-03 14:33:51 +0000571 expectedOrderedRuleOutputStream.write(bytesForPackage);
572 totalBytesWritten += bytesForPackage.length;
573 }
574 expectedIndexingBytesForPackageNameIndexed +=
Song Pane5d60742020-01-10 17:58:00 +0000575 SERIALIZED_END_INDEXING_KEY + getBits(totalBytesWritten, /* numOfBits= */ 32);
Omer Nebil Yaveroglu2935a212020-01-03 14:33:51 +0000576
577 String expectedIndexingBytesForAppCertificateIndexed =
Song Pane5d60742020-01-10 17:58:00 +0000578 SERIALIZED_START_INDEXING_KEY + getBits(totalBytesWritten, /* numOfBits= */ 32);
Omer Nebil Yaveroglu2935a212020-01-03 14:33:51 +0000579 for (int count = 0; count < ruleCount; count++) {
580 String appCertificate = String.format("%s%04d", appCertificatePrefix, count);
581 if (count > 0 && count % INDEXING_BLOCK_SIZE == 0) {
582 expectedIndexingBytesForAppCertificateIndexed +=
583 IS_NOT_HASHED
584 + getBits(appCertificate.length(), VALUE_SIZE_BITS)
585 + getValueBits(appCertificate)
586 + getBits(totalBytesWritten, /* numOfBits= */ 32);
587 }
588
589 byte[] bytesForPackage =
Song Pane5d60742020-01-10 17:58:00 +0000590 getBytes(
591 getSerializedCompoundRuleWithCertificateNameAndSampleInstallerName(
592 appCertificate));
Omer Nebil Yaveroglu2935a212020-01-03 14:33:51 +0000593 expectedOrderedRuleOutputStream.write(bytesForPackage);
594 totalBytesWritten += bytesForPackage.length;
595 }
596 expectedIndexingBytesForAppCertificateIndexed +=
Song Pane5d60742020-01-10 17:58:00 +0000597 SERIALIZED_END_INDEXING_KEY + getBits(totalBytesWritten, /* numOfBits= */ 32);
Omer Nebil Yaveroglu2935a212020-01-03 14:33:51 +0000598
599 String expectedIndexingBytesForUnindexed =
Song Pane5d60742020-01-10 17:58:00 +0000600 SERIALIZED_START_INDEXING_KEY + getBits(totalBytesWritten, /* numOfBits= */ 32);
Omer Nebil Yaveroglu2935a212020-01-03 14:33:51 +0000601 for (int count = 0; count < ruleCount; count++) {
602 byte[] bytesForPackage =
Song Pane5d60742020-01-10 17:58:00 +0000603 getBytes(
604 getSerializedCompoundRuleWithInstallerNameAndInstallerCert(
605 String.format("%s%04d", installerNamePrefix, count)));
Omer Nebil Yaveroglu2935a212020-01-03 14:33:51 +0000606 expectedOrderedRuleOutputStream.write(bytesForPackage);
607 totalBytesWritten += bytesForPackage.length;
608 }
609 expectedIndexingBytesForUnindexed +=
Song Pane5d60742020-01-10 17:58:00 +0000610 SERIALIZED_END_INDEXING_KEY + getBits(totalBytesWritten, /* numOfBits= */ 32);
Omer Nebil Yaveroglu8d46f342020-01-13 15:28:11 +0000611 expectedIndexingOutputStream.write(
Song Pane5d60742020-01-10 17:58:00 +0000612 getBytes(
613 expectedIndexingBytesForPackageNameIndexed
614 + expectedIndexingBytesForAppCertificateIndexed
615 + expectedIndexingBytesForUnindexed));
Omer Nebil Yaveroglu2935a212020-01-03 14:33:51 +0000616
617 assertThat(ruleOutputStream.toByteArray())
618 .isEqualTo(expectedOrderedRuleOutputStream.toByteArray());
619 assertThat(indexingOutputStream.toByteArray())
620 .isEqualTo(expectedIndexingOutputStream.toByteArray());
Omer Nebil Yaverogluf8047642019-12-20 14:57:15 +0000621 }
622
Omer Nebil Yaveroglu35e8f362020-01-17 10:54:10 +0000623 @Test
624 public void testBinaryString_totalRuleSizeLimitReached() {
625 int ruleCount = INDEXED_RULE_SIZE_LIMIT - 1;
626 String packagePrefix = "package.name.";
627 String appCertificatePrefix = "app.cert.";
628 String installerNamePrefix = "installer.";
629
630 // Create the rule set with more rules than the system can handle in total.
631 List<Rule> ruleList = new ArrayList();
632 for (int count = 0; count < ruleCount; count++) {
633 ruleList.add(
634 getRuleWithPackageNameAndSampleInstallerName(
635 String.format("%s%04d", packagePrefix, count)));
636 }
637 for (int count = 0; count < ruleCount; count++) {
638 ruleList.add(
639 getRuleWithAppCertificateAndSampleInstallerName(
640 String.format("%s%04d", appCertificatePrefix, count)));
641 }
642 for (int count = 0; count < NONINDEXED_RULE_SIZE_LIMIT - 1; count++) {
643 ruleList.add(
644 getNonIndexedRuleWithInstallerName(
645 String.format("%s%04d", installerNamePrefix, count)));
646 }
647
648 // Serialize the rules.
649 ByteArrayOutputStream ruleOutputStream = new ByteArrayOutputStream();
650 ByteArrayOutputStream indexingOutputStream = new ByteArrayOutputStream();
651 RuleSerializer binarySerializer = new RuleBinarySerializer();
652
653 assertExpectException(
654 RuleSerializeException.class,
655 "Too many rules provided",
656 () ->
657 binarySerializer.serialize(
658 ruleList,
659 /* formatVersion= */ Optional.empty(),
660 ruleOutputStream,
661 indexingOutputStream));
662 }
663
664 @Test
665 public void testBinaryString_tooManyPackageNameIndexedRules() {
666 String packagePrefix = "package.name.";
667
668 // Create a rule set with too many package name indexed rules.
669 List<Rule> ruleList = new ArrayList();
670 for (int count = 0; count < INDEXED_RULE_SIZE_LIMIT + 1; count++) {
671 ruleList.add(
672 getRuleWithPackageNameAndSampleInstallerName(
673 String.format("%s%04d", packagePrefix, count)));
674 }
675
676 // Serialize the rules.
677 ByteArrayOutputStream ruleOutputStream = new ByteArrayOutputStream();
678 ByteArrayOutputStream indexingOutputStream = new ByteArrayOutputStream();
679 RuleSerializer binarySerializer = new RuleBinarySerializer();
680
681 assertExpectException(
682 RuleSerializeException.class,
683 "Too many rules provided in the indexing group.",
684 () ->
685 binarySerializer.serialize(
686 ruleList,
687 /* formatVersion= */ Optional.empty(),
688 ruleOutputStream,
689 indexingOutputStream));
690 }
691
692 @Test
693 public void testBinaryString_tooManyAppCertificateIndexedRules() {
694 String appCertificatePrefix = "app.cert.";
695
696 // Create a rule set with too many app certificate indexed rules.
697 List<Rule> ruleList = new ArrayList();
698 for (int count = 0; count < INDEXED_RULE_SIZE_LIMIT + 1; count++) {
699 ruleList.add(
700 getRuleWithAppCertificateAndSampleInstallerName(
701 String.format("%s%04d", appCertificatePrefix, count)));
702 }
703
704 // Serialize the rules.
705 ByteArrayOutputStream ruleOutputStream = new ByteArrayOutputStream();
706 ByteArrayOutputStream indexingOutputStream = new ByteArrayOutputStream();
707 RuleSerializer binarySerializer = new RuleBinarySerializer();
708
709 assertExpectException(
710 RuleSerializeException.class,
711 "Too many rules provided in the indexing group.",
712 () ->
713 binarySerializer.serialize(
714 ruleList,
715 /* formatVersion= */ Optional.empty(),
716 ruleOutputStream,
717 indexingOutputStream));
718 }
719
720 @Test
721 public void testBinaryString_tooManyNonIndexedRules() {
722 String installerNamePrefix = "installer.";
723
724 // Create a rule set with too many unindexed rules.
725 List<Rule> ruleList = new ArrayList();
726 for (int count = 0; count < NONINDEXED_RULE_SIZE_LIMIT + 1; count++) {
727 ruleList.add(
728 getNonIndexedRuleWithInstallerName(
729 String.format("%s%04d", installerNamePrefix, count)));
730 }
731
732 // Serialize the rules.
733 ByteArrayOutputStream ruleOutputStream = new ByteArrayOutputStream();
734 ByteArrayOutputStream indexingOutputStream = new ByteArrayOutputStream();
735 RuleSerializer binarySerializer = new RuleBinarySerializer();
736
737 assertExpectException(
738 RuleSerializeException.class,
739 "Too many rules provided in the indexing group.",
740 () ->
741 binarySerializer.serialize(
742 ruleList,
743 /* formatVersion= */ Optional.empty(),
744 ruleOutputStream,
745 indexingOutputStream));
746 }
747
Omer Nebil Yaverogluf8047642019-12-20 14:57:15 +0000748 private Rule getRuleWithPackageNameAndSampleInstallerName(String packageName) {
749 return new Rule(
750 new CompoundFormula(
751 CompoundFormula.AND,
752 Arrays.asList(
753 new AtomicFormula.StringAtomicFormula(
754 AtomicFormula.PACKAGE_NAME,
755 packageName,
756 /* isHashedValue= */ false),
757 new AtomicFormula.StringAtomicFormula(
758 AtomicFormula.INSTALLER_NAME,
759 SAMPLE_INSTALLER_NAME,
760 /* isHashedValue= */ false))),
761 Rule.DENY);
762 }
763
764 private String getSerializedCompoundRuleWithPackageNameAndSampleInstallerName(
765 String packageName) {
766 return START_BIT
767 + COMPOUND_FORMULA_START_BITS
768 + AND
769 + ATOMIC_FORMULA_START_BITS
770 + PACKAGE_NAME
771 + EQ
772 + IS_NOT_HASHED
773 + getBits(packageName.length(), VALUE_SIZE_BITS)
774 + getValueBits(packageName)
775 + ATOMIC_FORMULA_START_BITS
776 + INSTALLER_NAME
777 + EQ
778 + IS_NOT_HASHED
779 + getBits(SAMPLE_INSTALLER_NAME.length(), VALUE_SIZE_BITS)
780 + getValueBits(SAMPLE_INSTALLER_NAME)
781 + COMPOUND_FORMULA_END_BITS
782 + DENY
783 + END_BIT;
784 }
785
786 private Rule getRuleWithAppCertificateAndSampleInstallerName(String certificate) {
787 return new Rule(
788 new CompoundFormula(
789 CompoundFormula.AND,
790 Arrays.asList(
791 new AtomicFormula.StringAtomicFormula(
792 AtomicFormula.APP_CERTIFICATE,
793 certificate,
794 /* isHashedValue= */ false),
795 new AtomicFormula.StringAtomicFormula(
796 AtomicFormula.INSTALLER_NAME,
797 SAMPLE_INSTALLER_NAME,
798 /* isHashedValue= */ false))),
799 Rule.DENY);
800 }
801
802 private String getSerializedCompoundRuleWithCertificateNameAndSampleInstallerName(
803 String appCertificate) {
804 return START_BIT
805 + COMPOUND_FORMULA_START_BITS
806 + AND
807 + ATOMIC_FORMULA_START_BITS
808 + APP_CERTIFICATE
809 + EQ
810 + IS_NOT_HASHED
811 + getBits(appCertificate.length(), VALUE_SIZE_BITS)
812 + getValueBits(appCertificate)
813 + ATOMIC_FORMULA_START_BITS
814 + INSTALLER_NAME
815 + EQ
816 + IS_NOT_HASHED
817 + getBits(SAMPLE_INSTALLER_NAME.length(), VALUE_SIZE_BITS)
818 + getValueBits(SAMPLE_INSTALLER_NAME)
819 + COMPOUND_FORMULA_END_BITS
820 + DENY
821 + END_BIT;
822 }
823
Omer Nebil Yaveroglu2935a212020-01-03 14:33:51 +0000824 private Rule getNonIndexedRuleWithInstallerName(String installerName) {
825 return new Rule(
826 new CompoundFormula(
827 CompoundFormula.AND,
828 Arrays.asList(
829 new AtomicFormula.StringAtomicFormula(
830 AtomicFormula.INSTALLER_NAME,
831 installerName,
832 /* isHashedValue= */ false),
833 new AtomicFormula.StringAtomicFormula(
834 AtomicFormula.INSTALLER_CERTIFICATE,
835 SAMPLE_INSTALLER_CERT,
836 /* isHashedValue= */ false))),
837 Rule.DENY);
838 }
839
840 private String getSerializedCompoundRuleWithInstallerNameAndInstallerCert(
841 String installerName) {
842 return START_BIT
843 + COMPOUND_FORMULA_START_BITS
844 + AND
845 + ATOMIC_FORMULA_START_BITS
846 + INSTALLER_NAME
847 + EQ
848 + IS_NOT_HASHED
849 + getBits(installerName.length(), VALUE_SIZE_BITS)
850 + getValueBits(installerName)
851 + ATOMIC_FORMULA_START_BITS
852 + INSTALLER_CERTIFICATE
853 + EQ
854 + IS_NOT_HASHED
855 + getBits(SAMPLE_INSTALLER_CERT.length(), VALUE_SIZE_BITS)
856 + getValueBits(SAMPLE_INSTALLER_CERT)
857 + COMPOUND_FORMULA_END_BITS
858 + DENY
859 + END_BIT;
860 }
861
Omer Nebil Yaveroglu15395f52020-01-22 12:14:44 +0000862 private static IntegrityFormula getInvalidFormula() {
863 return new AtomicFormula(0) {
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000864 @Override
865 public int getTag() {
866 return 0;
867 }
868
869 @Override
Omer Nebil Yaveroglu15395f52020-01-22 12:14:44 +0000870 public boolean matches(AppInstallMetadata appInstallMetadata) {
871 return false;
872 }
873
874 @Override
Omer Nebil Yaveroglu84f7c3f2020-01-29 12:18:10 +0000875 public boolean isAppCertificateFormula() {
876 return false;
877 }
878
879 @Override
880 public boolean isInstallerFormula() {
881 return false;
882 }
883
884 @Override
Khaled Abdelmohsen1fa4de52019-11-13 15:13:19 +0000885 public int hashCode() {
886 return super.hashCode();
887 }
888
889 @Override
890 public boolean equals(Object obj) {
891 return super.equals(obj);
892 }
893
894 @NonNull
895 @Override
896 protected Object clone() throws CloneNotSupportedException {
897 return super.clone();
898 }
899
900 @Override
901 public String toString() {
902 return super.toString();
903 }
904
905 @Override
906 protected void finalize() throws Throwable {
907 super.finalize();
908 }
909 };
910 }
911}