1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 extern crate key_enable;
16 extern crate ylong_json;
17
18 use std::thread;
19 use ylong_json::JsonValue;
20 use key_enable::cert_chain_utils::PemCollection;
21 use key_enable::cert_path_utils::TrustCertPath;
22 use key_enable::profile_utils::{UDID, get_udid, validate_bundle_and_distribution_type};
23
24
25 // pem_cert_file
26 const VALID_PEM_CERT: &str = "/data/test/tmp/valid_pem_cert.json";
27 const NON_EXISTEND_PEM_CERT: &str = "/data/test/tmp/non_existent_cert_path.json";
28 const INVALID_STRUCTURE_PEM_CERT: &str = "/data/test/tmp/invalid_structure_cert_path.json";
29 const EMPTY_PEM_CERT: &str = "/data/test/tmp/empty_pem_cert.json";
30 // cert_path_file
31 const VALID_CERT_PATH: &str = "/data/test/tmp/valid_cert_path.json";
32 const NON_EXISTEND_CERT_PATH: &str = "/data/test/tmp/non_existent_cert_path.json";
33 const INVALID_STRUCTURE_CERT_PATH: &str = "/data/test/tmp/invalid_structure_cert_path.json";
34 const EMPTY_CERT_PATH: &str = "/data/test/tmp/empty_cert_path.json";
35
36 const ALLOWED_ROOT_CERT_MEMBER_NAMES: &[&str] = &[
37 "C=CN, O=Huawei, OU=Huawei CBG, CN=Huawei CBG Root CA G2",
38 "C=CN, O=OpenHarmony, OU=OpenHarmony Team, CN=OpenHarmony Application Root CA",
39 "C=CN, O=Huawei, OU=Huawei CBG, CN=Huawei CBG Root CA G2 Test",
40 ];
41
42 #[test]
test_load_pem_cert_from_valid_json_file()43 fn test_load_pem_cert_from_valid_json_file() {
44 // test is_debuggable true
45 let mut root_cert = PemCollection::new();
46 root_cert.load_pem_certs_from_json_file(VALID_PEM_CERT, ALLOWED_ROOT_CERT_MEMBER_NAMES);
47 assert_eq!(root_cert.pem_data.len(), 3);
48 }
49
50 #[test]
test_invalid_pem_cert_file_path()51 fn test_invalid_pem_cert_file_path() {
52 let mut root_cert = PemCollection::new();
53 root_cert.load_pem_certs_from_json_file(NON_EXISTEND_PEM_CERT, ALLOWED_ROOT_CERT_MEMBER_NAMES);
54 assert!(root_cert.pem_data.is_empty());
55 }
56
57 #[test]
test_invalid_pem_cert_json_structure()58 fn test_invalid_pem_cert_json_structure() {
59 let mut root_cert = PemCollection::new();
60 root_cert
61 .load_pem_certs_from_json_file(INVALID_STRUCTURE_PEM_CERT, ALLOWED_ROOT_CERT_MEMBER_NAMES);
62 assert!(root_cert.pem_data.is_empty());
63 }
64
65 #[test]
test_empty_pem_cert_json_file()66 fn test_empty_pem_cert_json_file() {
67 let mut root_cert = PemCollection::new();
68 root_cert.load_pem_certs_from_json_file(EMPTY_PEM_CERT, ALLOWED_ROOT_CERT_MEMBER_NAMES);
69 assert!(root_cert.pem_data.is_empty());
70 }
71
72 #[test]
test_successful_load_cert_path()73 fn test_successful_load_cert_path() {
74 let mut cert_paths = TrustCertPath::new();
75 cert_paths.load_cert_path_from_json_file(VALID_CERT_PATH);
76 assert_eq!(cert_paths.profile_signers.len(), 4);
77 assert_eq!(cert_paths.app_sources.len(), 6);
78 }
79 #[test]
test_invalid_cert_path_file_path()80 fn test_invalid_cert_path_file_path() {
81 let mut cert_paths = TrustCertPath::new();
82 cert_paths.load_cert_path_from_json_file(NON_EXISTEND_CERT_PATH);
83 assert!(
84 cert_paths.app_sources.is_empty(),
85 "Expected cert_paths.app_sources to be empty for an empty JSON file"
86 );
87 }
88
89 #[test]
test_invalid_cert_path_json_structure()90 fn test_invalid_cert_path_json_structure() {
91 let mut cert_paths = TrustCertPath::new();
92 cert_paths.load_cert_path_from_json_file(INVALID_STRUCTURE_CERT_PATH);
93 assert!(
94 cert_paths.app_sources.is_empty(),
95 "Expected cert_paths.app_sources to be empty for an empty JSON file"
96 );
97 }
98
99 #[test]
test_empty_cert_path_json_file()100 fn test_empty_cert_path_json_file() {
101 let mut cert_paths = TrustCertPath::new();
102 cert_paths.load_cert_path_from_json_file(EMPTY_CERT_PATH);
103 assert!(
104 cert_paths.app_sources.is_empty(),
105 "Expected cert_paths.app_sources to be empty for an empty JSON file"
106 );
107 }
108
109 #[test]
test_parse_enterprise_profile()110 fn test_parse_enterprise_profile() {
111 let profile_str = r#"
112 {
113 "version-name": "2.0.0",
114 "version-code": 2,
115 "app-distribution-type": "enterprise",
116 "uuid": "",
117 "validity": {
118 "not-before": 1,
119 "not-after": 2
120 },
121 "type": "release",
122 "bundle-info": {
123 "developer-id": "",
124 "distribution-certificate": "",
125 "bundle-name": "com.test.enterprise",
126 "apl": "normal",
127 "app-feature": "test_app",
128 "app-identifier": "123123"
129 },
130 "acls": {
131 "allowed-acls": [
132 ""
133 ]
134 },
135 "app-privilege-capabilities": [],
136 "permissions": {
137 "restricted-permissions": [
138 ""
139 ]
140 }
141 }
142 "#;
143 let profile_json =JsonValue::from_text(profile_str).unwrap();
144 let result = validate_bundle_and_distribution_type(&profile_json, true);
145 assert!(result.is_ok());
146 }
147
148 #[test]
test_parse_enterprise_normal_profile()149 fn test_parse_enterprise_normal_profile() {
150 let profile_str = r#"
151 {
152 "version-name": "2.0.0",
153 "version-code": 2,
154 "app-distribution-type": "enterprise_normal",
155 "uuid": "",
156 "validity": {
157 "not-before": 1,
158 "not-after": 2
159 },
160 "type": "release",
161 "bundle-info": {
162 "developer-id": "",
163 "distribution-certificate": "",
164 "bundle-name": "com.test.enterprise_normal",
165 "apl": "normal",
166 "app-feature": "test_app",
167 "app-identifier": "123123"
168 },
169 "acls": {
170 "allowed-acls": [
171 ""
172 ]
173 },
174 "app-privilege-capabilities": [],
175 "permissions": {
176 "restricted-permissions": [
177 ""
178 ]
179 }
180 }
181 "#;
182 let profile_json =JsonValue::from_text(profile_str).unwrap();
183 let result = validate_bundle_and_distribution_type(&profile_json, true);
184 assert!(result.is_ok());
185 }
186
187 #[test]
test_parse_enterprise_mdm_profile()188 fn test_parse_enterprise_mdm_profile() {
189 let profile_str = r#"
190 {
191 "version-name": "2.0.0",
192 "version-code": 2,
193 "app-distribution-type": "enterprise_mdm",
194 "uuid": "",
195 "validity": {
196 "not-before": 1,
197 "not-after": 2
198 },
199 "type": "release",
200 "bundle-info": {
201 "developer-id": "",
202 "distribution-certificate": "",
203 "bundle-name": "com.test.enterprise_mdm",
204 "apl": "normal",
205 "app-feature": "test_app",
206 "app-identifier": "123123"
207 },
208 "acls": {
209 "allowed-acls": [
210 ""
211 ]
212 },
213 "app-privilege-capabilities": [],
214 "permissions": {
215 "restricted-permissions": [
216 ""
217 ]
218 }
219 }
220 "#;
221 let profile_json =JsonValue::from_text(profile_str).unwrap();
222 let result = validate_bundle_and_distribution_type(&profile_json, true);
223 assert!(result.is_ok());
224 }
225
226 #[test]
test_parse_debug_profile()227 fn test_parse_debug_profile() {
228 let profile_str = r#"
229 {
230 "version-name": "2.0.0",
231 "version-code": 2,
232 "app-distribution-type": "developer",
233 "uuid": "",
234 "validity": {
235 "not-before": 1,
236 "not-after": 2
237 },
238 "type": "debug",
239 "bundle-info": {
240 "developer-id": "",
241 "development-certificate": "",
242 "bundle-name": "com.test.developer",
243 "apl": "normal",
244 "app-feature": "test_app",
245 "app-identifier": "123123"
246 },
247 "acls": {
248 "allowed-acls": [
249 ""
250 ]
251 },
252 "app-privilege-capabilities": [],
253 "permissions": {
254 "restricted-permissions": [
255 ""
256 ]
257 },
258 "debug-info": {
259 "device-ids": [],
260 "device-id-type": "udid"
261 }
262 }
263 "#;
264 let udid = get_udid().expect("Failed to get UDID");
265 let mut profile_json =JsonValue::from_text(profile_str).unwrap();
266 profile_json["debug-info"]["device-ids"][0] = JsonValue::String(udid);
267 let result = validate_bundle_and_distribution_type(&profile_json, true);
268 assert!(result.is_ok());
269 }
270
271 #[test]
test_parse_iternaltesting_profile()272 fn test_parse_iternaltesting_profile() {
273 let profile_str = r#"
274 {
275 "version-name": "2.0.0",
276 "version-code": 2,
277 "app-distribution-type": "internaltesting",
278 "uuid": "",
279 "validity": {
280 "not-before": 1,
281 "not-after": 2
282 },
283 "type": "release",
284 "bundle-info": {
285 "developer-id": "",
286 "distribution-certificate": "",
287 "bundle-name": "com.test.internaltesting",
288 "apl": "normal",
289 "app-feature": "test_app",
290 "app-identifier": "123123"
291 },
292 "acls": {
293 "allowed-acls": [
294 ""
295 ]
296 },
297 "app-privilege-capabilities": [],
298 "permissions": {
299 "restricted-permissions": [
300 ""
301 ]
302 },
303 "debug-info": {
304 "device-ids": [],
305 "device-id-type": "udid"
306 }
307 }
308 "#;
309 let udid = get_udid().expect("Failed to get UDID");
310 let mut profile_json =JsonValue::from_text(profile_str).unwrap();
311 profile_json["debug-info"]["device-ids"][0] = JsonValue::String(udid);
312 let result = validate_bundle_and_distribution_type(&profile_json, true);
313 assert!(result.is_ok());
314 }
315
316 #[test]
test_parse_invalid_profile()317 fn test_parse_invalid_profile() {
318 let no_type_profile = r#"
319 {
320 "version-name": "2.0.0",
321 "version-code": 2,
322 "app-distribution-type": "internaltesting",
323 "uuid": "",
324 "validity": {
325 "not-before": 1,
326 "not-after": 2
327 },
328 "bundle-info": {
329 "developer-id": "",
330 "distribution-certificate": "",
331 "bundle-name": "com.test.internaltesting",
332 "apl": "normal",
333 "app-feature": "test_app",
334 "app-identifier": "123123"
335 },
336 "acls": {
337 "allowed-acls": [
338 ""
339 ]
340 },
341 "app-privilege-capabilities": [],
342 "permissions": {
343 "restricted-permissions": [
344 ""
345 ]
346 },
347 "debug-info": {
348 "device-ids": [],
349 "device-id-type": "udid"
350 }
351 }
352 "#;
353 let no_distribution_profile = r#"
354 {
355 "version-name": "2.0.0",
356 "version-code": 2,
357 "uuid": "",
358 "validity": {
359 "not-before": 1,
360 "not-after": 2
361 },
362 "type": "release",
363 "bundle-info": {
364 "developer-id": "",
365 "distribution-certificate": "",
366 "bundle-name": "com.test.internaltesting",
367 "apl": "normal",
368 "app-feature": "test_app",
369 "app-identifier": "123123"
370 },
371 "acls": {
372 "allowed-acls": [
373 ""
374 ]
375 },
376 "app-privilege-capabilities": [],
377 "permissions": {
378 "restricted-permissions": [
379 ""
380 ]
381 },
382 "debug-info": {
383 "device-ids": [],
384 "device-id-type": "udid"
385 }
386 }
387 "#;
388 let no_debug_info_profile = r#"
389 {
390 "version-name": "2.0.0",
391 "version-code": 2,
392 "app-distribution-type": "internaltesting",
393 "uuid": "",
394 "validity": {
395 "not-before": 1,
396 "not-after": 2
397 },
398 "type": "release",
399 "bundle-info": {
400 "developer-id": "",
401 "distribution-certificate": "",
402 "bundle-name": "com.test.internaltesting",
403 "apl": "normal",
404 "app-feature": "test_app",
405 "app-identifier": "123123"
406 },
407 "acls": {
408 "allowed-acls": [
409 ""
410 ]
411 },
412 "app-privilege-capabilities": [],
413 "permissions": {
414 "restricted-permissions": [
415 ""
416 ]
417 }
418 }
419 "#;
420 let udid = get_udid().expect("Failed to get UDID");
421 let mut no_type_profile_json =JsonValue::from_text(no_type_profile).unwrap();
422 no_type_profile_json["debug-info"]["device-ids"][0] = JsonValue::String(udid.clone());
423 let result = validate_bundle_and_distribution_type(&no_type_profile_json, true);
424 assert!(result.is_err());
425
426 let mut no_distribution_profile_json =JsonValue::from_text(no_distribution_profile).unwrap();
427 no_distribution_profile_json["debug-info"]["device-ids"][0] = JsonValue::String(udid.clone());
428 let result = validate_bundle_and_distribution_type(&no_distribution_profile_json, true);
429 assert!(result.is_err());
430
431 let no_debug_info_profile_json =JsonValue::from_text(no_debug_info_profile).unwrap();
432 let result = validate_bundle_and_distribution_type(&no_debug_info_profile_json, true);
433 assert!(result.is_err());
434 }
435
436 #[test]
test_get_udid_once()437 fn test_get_udid_once() {
438 let udid_from_get = get_udid().expect("Failed to get UDID");
439 let udid_from_global = UDID.clone().expect("UDID is None");
440
441 assert_eq!(udid_from_get, udid_from_global);
442 }
443
444 #[test]
test_get_udid_concurrent()445 fn test_get_udid_concurrent() {
446 let num_threads = 10;
447 let mut handles = vec![];
448
449 for _ in 0..num_threads {
450 let handle = thread::spawn(|| {
451 let udid = get_udid().expect("Failed to get UDID");
452 assert_eq!(udid, UDID.clone().expect("UDID is None"));
453 });
454 handles.push(handle);
455 }
456
457 for handle in handles {
458 handle.join().expect("Thread panicked");
459 }
460 }