1 /*
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 
17 package com.android.internal.widget;
18 
19 
20 import static com.google.common.truth.Truth.assertThat;
21 
22 import android.test.AndroidTestCase;
23 
24 import java.util.Arrays;
25 
26 
27 public class LockscreenCredentialTest extends AndroidTestCase {
28 
testEmptyCredential()29     public void testEmptyCredential() {
30         LockscreenCredential empty = LockscreenCredential.createNone();
31 
32         assertTrue(empty.isNone());
33         assertEquals(0, empty.size());
34         assertNotNull(empty.getCredential());
35 
36         assertFalse(empty.isPin());
37         assertFalse(empty.isPassword());
38         assertFalse(empty.isPattern());
39     }
40 
testPinCredential()41     public void testPinCredential() {
42         LockscreenCredential pin = LockscreenCredential.createPin("3456");
43 
44         assertTrue(pin.isPin());
45         assertEquals(4, pin.size());
46         assertTrue(Arrays.equals("3456".getBytes(), pin.getCredential()));
47 
48         assertFalse(pin.isNone());
49         assertFalse(pin.isPassword());
50         assertFalse(pin.isPattern());
51     }
52 
testPasswordCredential()53     public void testPasswordCredential() {
54         LockscreenCredential password = LockscreenCredential.createPassword("password");
55 
56         assertTrue(password.isPassword());
57         assertEquals(8, password.size());
58         assertTrue(Arrays.equals("password".getBytes(), password.getCredential()));
59 
60         assertFalse(password.isNone());
61         assertFalse(password.isPin());
62         assertFalse(password.isPattern());
63     }
64 
testPatternCredential()65     public void testPatternCredential() {
66         LockscreenCredential pattern = LockscreenCredential.createPattern(Arrays.asList(
67                 LockPatternView.Cell.of(0, 0),
68                 LockPatternView.Cell.of(0, 1),
69                 LockPatternView.Cell.of(0, 2),
70                 LockPatternView.Cell.of(1, 2),
71                 LockPatternView.Cell.of(2, 2)
72                 ));
73 
74         assertTrue(pattern.isPattern());
75         assertEquals(5, pattern.size());
76         assertTrue(Arrays.equals("12369".getBytes(), pattern.getCredential()));
77 
78         assertFalse(pattern.isNone());
79         assertFalse(pattern.isPin());
80         assertFalse(pattern.isPassword());
81     }
82 
testPasswordOrNoneCredential()83     public void testPasswordOrNoneCredential() {
84         assertEquals(LockscreenCredential.createNone(),
85                 LockscreenCredential.createPasswordOrNone(null));
86         assertEquals(LockscreenCredential.createNone(),
87                 LockscreenCredential.createPasswordOrNone(""));
88         assertEquals(LockscreenCredential.createPassword("abcd"),
89                 LockscreenCredential.createPasswordOrNone("abcd"));
90     }
91 
testPinOrNoneCredential()92     public void testPinOrNoneCredential() {
93         assertEquals(LockscreenCredential.createNone(),
94                 LockscreenCredential.createPinOrNone(null));
95         assertEquals(LockscreenCredential.createNone(),
96                 LockscreenCredential.createPinOrNone(""));
97         assertEquals(LockscreenCredential.createPin("1357"),
98                 LockscreenCredential.createPinOrNone("1357"));
99     }
100 
testSanitize()101     public void testSanitize() {
102         LockscreenCredential password = LockscreenCredential.createPassword("password");
103         password.zeroize();
104 
105         try {
106             password.isNone();
107             fail("Sanitized credential still accessible");
108         } catch (IllegalStateException expected) { }
109         try {
110             password.isPattern();
111             fail("Sanitized credential still accessible");
112         } catch (IllegalStateException expected) { }
113         try {
114             password.isPin();
115             fail("Sanitized credential still accessible");
116         } catch (IllegalStateException expected) { }
117         try {
118             password.isPassword();
119             fail("Sanitized credential still accessible");
120         } catch (IllegalStateException expected) { }
121         try {
122             password.size();
123             fail("Sanitized credential still accessible");
124         } catch (IllegalStateException expected) { }
125         try {
126             password.getCredential();
127             fail("Sanitized credential still accessible");
128         } catch (IllegalStateException expected) { }
129     }
130 
testEquals()131     public void testEquals() {
132         assertEquals(LockscreenCredential.createNone(), LockscreenCredential.createNone());
133         assertEquals(LockscreenCredential.createPassword("1234"),
134                 LockscreenCredential.createPassword("1234"));
135         assertEquals(LockscreenCredential.createPin("4321"),
136                 LockscreenCredential.createPin("4321"));
137         assertEquals(createPattern("1234"), createPattern("1234"));
138 
139         assertNotSame(LockscreenCredential.createPassword("1234"),
140                 LockscreenCredential.createNone());
141         assertNotSame(LockscreenCredential.createPassword("1234"),
142                 LockscreenCredential.createPassword("4321"));
143         assertNotSame(LockscreenCredential.createPassword("1234"),
144                 createPattern("1234"));
145         assertNotSame(LockscreenCredential.createPassword("1234"),
146                 LockscreenCredential.createPin("1234"));
147 
148         assertNotSame(LockscreenCredential.createPin("1111"),
149                 LockscreenCredential.createNone());
150         assertNotSame(LockscreenCredential.createPin("1111"),
151                 LockscreenCredential.createPin("2222"));
152         assertNotSame(LockscreenCredential.createPin("1111"),
153                 createPattern("1111"));
154         assertNotSame(LockscreenCredential.createPin("1111"),
155                 LockscreenCredential.createPassword("1111"));
156 
157         assertNotSame(createPattern("5678"),
158                 LockscreenCredential.createNone());
159         assertNotSame(createPattern("5678"),
160                 createPattern("1234"));
161         assertNotSame(createPattern("5678"),
162                 LockscreenCredential.createPassword("5678"));
163         assertNotSame(createPattern("5678"),
164                 LockscreenCredential.createPin("5678"));
165     }
166 
testDuplicate()167     public void testDuplicate() {
168         LockscreenCredential credential;
169 
170         credential = LockscreenCredential.createNone();
171         assertEquals(credential, credential.duplicate());
172         credential = LockscreenCredential.createPassword("abcd");
173         assertEquals(credential, credential.duplicate());
174         credential = LockscreenCredential.createPin("1234");
175         assertEquals(credential, credential.duplicate());
176         credential = createPattern("5678");
177         assertEquals(credential, credential.duplicate());
178     }
179 
testPasswordToHistoryHash()180     public void testPasswordToHistoryHash() {
181         String password = "1234";
182         LockscreenCredential credential = LockscreenCredential.createPassword(password);
183         String hashFactor = "6637D20C0798382D9F1304861C81DE222BC6CB7183623C67DA99B115A7AF702D";
184         String salt = "6d5331dd120077a0";
185         String expectedHash = "BCFB17409F2CD0A00D8627F76D080FB547B0B6A30CB7A375A34720D2312EDAC7";
186 
187         assertThat(
188                 credential.passwordToHistoryHash(salt.getBytes(), hashFactor.getBytes()))
189                 .isEqualTo(expectedHash);
190         assertThat(
191                 LockscreenCredential.passwordToHistoryHash(
192                         password.getBytes(), salt.getBytes(), hashFactor.getBytes()))
193                 .isEqualTo(expectedHash);
194     }
195 
testPasswordToHistoryHashInvalidInput()196     public void testPasswordToHistoryHashInvalidInput() {
197         String password = "1234";
198         LockscreenCredential credential = LockscreenCredential.createPassword(password);
199         String hashFactor = "6637D20C0798382D9F1304861C81DE222BC6CB7183623C67DA99B115A7AF702D";
200         String salt = "6d5331dd120077a0";
201 
202         assertThat(
203                 credential.passwordToHistoryHash(/* salt= */ null, hashFactor.getBytes()))
204                 .isNull();
205         assertThat(
206                 LockscreenCredential.passwordToHistoryHash(
207                         password.getBytes(), /* salt= */ null, hashFactor.getBytes()))
208                 .isNull();
209 
210         assertThat(
211                 credential.passwordToHistoryHash(salt.getBytes(), /* hashFactor= */ null))
212                 .isNull();
213         assertThat(
214                 LockscreenCredential.passwordToHistoryHash(
215                         password.getBytes(), salt.getBytes(), /* hashFactor= */ null))
216                 .isNull();
217 
218         assertThat(
219                 LockscreenCredential.passwordToHistoryHash(
220                         /* password= */ null, salt.getBytes(), hashFactor.getBytes()))
221                 .isNull();
222     }
223 
testLegacyPasswordToHash()224     public void testLegacyPasswordToHash() {
225         String password = "1234";
226         String salt = "6d5331dd120077a0";
227         String expectedHash =
228                 "2DD04348ADBF8F4CABD7F722DC2E2887FAD4B6020A0C3E02C831E09946F0554FDC13B155";
229 
230         assertThat(
231                 LockscreenCredential.legacyPasswordToHash(
232                         password.getBytes(), salt.getBytes()))
233                 .isEqualTo(expectedHash);
234     }
235 
testLegacyPasswordToHashInvalidInput()236     public void testLegacyPasswordToHashInvalidInput() {
237         String password = "1234";
238         String salt = "6d5331dd120077a0";
239 
240         assertThat(LockscreenCredential.legacyPasswordToHash(
241                 password.getBytes(), /* salt= */ null)).isNull();
242 
243         assertThat(
244                 LockscreenCredential.legacyPasswordToHash(
245                         /* password= */ null, salt.getBytes()))
246                 .isNull();
247     }
248 
createPattern(String patternString)249     private LockscreenCredential createPattern(String patternString) {
250         return LockscreenCredential.createPattern(LockPatternUtils.byteArrayToPattern(
251                 patternString.getBytes()));
252     }
253 }
254