1 /*
2  * Copyright (C) 2020 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 
17 package com.android.certinstaller;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import android.content.Context;
22 import android.content.Intent;
23 import android.security.Credentials;
24 import android.security.KeyChain;
25 import android.security.keystore.KeyProperties;
26 import android.os.Process;
27 
28 import org.junit.Before;
29 import org.junit.Test;
30 import org.junit.runner.RunWith;
31 import org.robolectric.Robolectric;
32 import org.robolectric.RobolectricTestRunner;
33 import org.robolectric.RuntimeEnvironment;
34 import org.robolectric.android.controller.ActivityController;
35 
36 @RunWith(RobolectricTestRunner.class)
37 public final class CertInstallerRoboTest {
38 
39     private Context mContext;
40 
41     @Before
setUp()42     public void setUp() {
43         mContext = RuntimeEnvironment.application.getApplicationContext();
44     }
45 
46     @Test
testNameNotNullPass()47     public void testNameNotNullPass() throws Exception {
48         Intent intent = new Intent(mContext, CertInstaller.class);
49         intent.putExtra(KeyChain.EXTRA_NAME, "name");
50         CredentialHelper helper = startActivityAndGetCredentialHelper(intent);
51 
52         assertThat(helper.getName()).isEqualTo("name");
53     }
54 
55     @Test
testReferrerNotNullPass()56     public void testReferrerNotNullPass() throws Exception {
57         Intent intent = new Intent(mContext, CertInstaller.class);
58         intent.putExtra(Intent.EXTRA_REFERRER, "referrer");
59         CredentialHelper helper = startActivityAndGetCredentialHelper(intent);
60 
61         assertThat(helper.getReferrer()).isEqualTo("referrer");
62     }
63 
64     /**
65      * mUid should be ignored if EXTRA_CERTIFICATE_USAGE is provided.
66      * if EXTRA_CERTIFICATE_USAGE equals CERTIFICATE_USAGE_WIFI,
67      * mUid should equal Process.WIFI_UID
68      */
69     @Test
testUidUsageEqualWifiPass()70     public void testUidUsageEqualWifiPass() throws Exception {
71         Intent intent = new Intent(mContext, CertInstaller.class);
72         intent.putExtra(Credentials.EXTRA_INSTALL_AS_UID, Process.INVALID_UID);
73         intent.putExtra(Credentials.EXTRA_CERTIFICATE_USAGE, Credentials.CERTIFICATE_USAGE_WIFI);
74 
75         CredentialHelper helper = startActivityAndGetCredentialHelper(intent);
76 
77         assertThat(helper.getCertUsageSelected()).isEqualTo(Credentials.CERTIFICATE_USAGE_WIFI);
78         assertThat(helper.getUid()).isEqualTo(Process.WIFI_UID);
79 
80     }
81 
82     /**
83      * mUid should be ignored if EXTRA_CERTIFICATE_USAGE is provided.
84      * if EXTRA_CERTIFICATE_USAGE does not equal CERTIFICATE_USAGE_WIFI,
85      * mUid should equal KeyProperties.UID_SELF
86      */
87     @Test
testUidUsageNotNullPass()88     public void testUidUsageNotNullPass() throws Exception {
89         Intent intent = new Intent(mContext, CertInstaller.class);
90         intent.putExtra(Credentials.EXTRA_INSTALL_AS_UID, Process.INVALID_UID);
91         intent.putExtra(Credentials.EXTRA_CERTIFICATE_USAGE, "usage");
92 
93         CredentialHelper helper = startActivityAndGetCredentialHelper(intent);
94 
95         assertThat(helper.getUid()).isEqualTo(KeyProperties.UID_SELF);
96         assertThat(helper.getCertUsageSelected()).isEqualTo("usage");
97     }
98 
99     /**
100      * if EXTRA_CERTIFICATE_USAGE is not provided,
101      * mUid should equal the Credentials.EXTRA_INSTALL_AS_UID extra
102      */
103     @Test
testUidUsageNullPass()104     public void testUidUsageNullPass() throws Exception {
105         Intent intent = new Intent(mContext, CertInstaller.class);
106         intent.putExtra(Credentials.EXTRA_INSTALL_AS_UID, 100);
107 
108         CredentialHelper helper = startActivityAndGetCredentialHelper(intent);
109 
110         assertThat(helper.getUid()).isEqualTo(100);
111     }
112 
113     @Test
testIntentGetsMultipleKeysPass()114     public void testIntentGetsMultipleKeysPass() throws Exception {
115         Intent intent = new Intent(mContext, CertInstaller.class);
116         intent.putExtra("key1", CA_CERTIFICATE_1);
117         intent.putExtra("key2", CA_CERTIFICATE_2);
118 
119         CredentialHelper helper = startActivityAndGetCredentialHelper(intent);
120 
121         assertThat(helper.getData("key1")).isEqualTo(CA_CERTIFICATE_1);
122         assertThat(helper.getData("key2")).isEqualTo(CA_CERTIFICATE_2);
123     }
124     @Test
testIntentNullPass()125     public void testIntentNullPass() throws Exception {
126         Intent intent = new Intent(mContext, CertInstaller.class);
127 
128         CredentialHelper helper = startActivityAndGetCredentialHelper(intent);
129 
130         assertThat(!helper.containsAnyRawData()).isTrue();
131         assertThat(helper.getName()).isEqualTo("");
132         assertThat(helper.getUid()).isEqualTo(Process.INVALID_UID);
133         assertThat(helper.getReferrer()).isEqualTo("");
134         assertThat(helper.getCertUsageSelected()).isEqualTo("");
135     }
136 
startActivityAndGetCredentialHelper(Intent intent)137     private CredentialHelper startActivityAndGetCredentialHelper(Intent intent) {
138         ActivityController<CertInstaller> controller =
139                 Robolectric.buildActivity(CertInstaller.class, intent);
140 
141         CertInstaller activity = controller
142                 .create()
143                 .start()
144                 .resume()
145                 .visible()
146                 .get();
147         return activity.getCredentials();
148     }
149 
150     public static final byte[] CA_CERTIFICATE_1 = new byte[]{
151             (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x8a, (byte) 0x30, (byte) 0x82
152     };
153 
154     public static final byte[] CA_CERTIFICATE_2 = new byte[]{
155             (byte) 0x01, (byte) 0xf3, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01
156     };
157 
158 }