1 /*
2 * Copyright (c) 2023-2024 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
16 use lazy_static::lazy_static;
17 use super::cert_chain_utils::PemCollection;
18 use super::cert_path_utils::{
19 add_cert_path_info, remove_cert_path_info, common_format_fabricate_name,
20 DebugCertPathType, ReleaseCertPathType, TrustCertPath,
21 };
22 use super::cs_hisysevent::report_parse_profile_err;
23 use super::file_utils::{
24 create_file_path, delete_file_path, file_exists, fmt_store_path,
25 load_bytes_from_file, write_bytes_to_file, change_default_mode_file, change_default_mode_directory
26 };
27 use hilog_rust::{error, info, hilog, HiLogLabel, LogType};
28 use openssl::pkcs7::{Pkcs7, Pkcs7Flags};
29 use openssl::stack::Stack;
30 use openssl::x509::store::{X509Store, X509StoreBuilder};
31 use openssl::x509::{X509NameRef, X509};
32 use std::error::Error;
33 use std::ffi::{c_char, CStr, CString};
34 use std::fs::read_dir;
35 use ylong_json::JsonValue;
36
37 const ERROR_CODE: i32 = -1;
38 const SUCCESS_CODE: i32 = 0;
39 const LOG_LABEL: HiLogLabel = HiLogLabel {
40 log_type: LogType::LogCore,
41 domain: 0xd005a06, // security domain
42 tag: "CODE_SIGN",
43 };
44 const PROFILE_STORE_EL0_PREFIX: &str = "/data/service/el0/profiles/developer";
45 const PROFILE_STORE_EL1_PREFIX: &str = "/data/service/el1/profiles/release";
46 const PROFILE_STORE_EL1_PUBLIC_PREFIX: &str = "/data/service/el1/public/profiles/release";
47 const DEBUG_PROFILE_STORE_EL0_PREFIX: &str = "/data/service/el0/profiles/debug";
48 const DEBUG_PROFILE_STORE_EL1_PREFIX: &str = "/data/service/el1/profiles/debug";
49 const DEBUG_PROFILE_STORE_EL1_PUBLIC_PREFIX: &str = "/data/service/el1/public/profiles/debug";
50 const PROFILE_STORE_TAIL: &str = "profile.p7b";
51 const PROFILE_TYPE_KEY: &str = "type";
52 const PROFILE_DEVICE_ID_TYPE_KEY: &str = "device-id-type";
53 const PROFILE_DEBUG_INFO_KEY: &str = "debug-info";
54 const PROFILE_DEVICE_IDS_KEY: &str = "device-ids";
55 const PROFILE_BUNDLE_INFO_KEY: &str = "bundle-info";
56 const PROFILE_BUNDLE_INFO_RELEASE_KEY: &str = "distribution-certificate";
57 const PROFILE_BUNDLE_INFO_DEBUG_KEY: &str = "development-certificate";
58 const PROFILE_APP_DISTRIBUTION_TYPE_KEY: &str = "app-distribution-type";
59 const PROFILE_APP_IDENTIFIER_KEY: &str = "app-identifier";
60 const APP_DISTRIBUTION_TYPE_INTERNALTESTING: &str = "internaltesting";
61 const APP_DISTRIBUTION_TYPE_ENTERPRISE: &str = "enterprise";
62 const APP_DISTRIBUTION_TYPE_ENTERPRISE_NORMAL: &str = "enterprise_normal";
63 const APP_DISTRIBUTION_TYPE_ENTERPRISE_MDM: &str = "enterprise_mdm";
64 const DEFAULT_MAX_CERT_PATH_LEN: u32 = 3;
65 const PROFILE_RELEASE_TYPE: &str = "release";
66 const PROFILE_DEBUG_TYPE: &str = "debug";
67 const EMPTY_APP_ID: &str = "";
68
69 /// profile error
70 pub enum ProfileError {
71 /// add cert path error
72 AddCertPathError,
73 }
74 /// profile error report to hisysevent
75 pub enum HisyseventProfileError {
76 /// release platform code
77 VerifySigner = 1,
78 /// release authed code
79 ParsePkcs7 = 2,
80 /// release developer code
81 AddCertPath = 3,
82 }
83
84 extern "C" {
85 /// if developer state on return true
IsDeveloperModeOn() -> bool86 pub fn IsDeveloperModeOn() -> bool;
CodeSignGetUdid(udid: *mut u8) -> i3287 fn CodeSignGetUdid(udid: *mut u8) -> i32;
IsRdDevice() -> bool88 fn IsRdDevice() -> bool;
89 }
90
91 #[no_mangle]
92 /// the interface to enable key in profile
EnableKeyInProfileByRust( bundle_name: *const c_char, profile: *const u8, profile_size: u32, ) -> i3293 pub extern "C" fn EnableKeyInProfileByRust(
94 bundle_name: *const c_char,
95 profile: *const u8,
96 profile_size: u32,
97 ) -> i32 {
98 match enable_key_in_profile_internal(bundle_name, profile, profile_size) {
99 Ok(_) => SUCCESS_CODE,
100 Err(_) => ERROR_CODE,
101 }
102 }
103
104 #[no_mangle]
105 /// the interface remove key in profile
RemoveKeyInProfileByRust(bundle_name: *const c_char) -> i32106 pub extern "C" fn RemoveKeyInProfileByRust(bundle_name: *const c_char) -> i32 {
107 match remove_key_in_profile_internal(bundle_name) {
108 Ok(_) => SUCCESS_CODE,
109 Err(_) => ERROR_CODE,
110 }
111 }
112
parse_pkcs7_data( pkcs7: &Pkcs7, root_store: &X509Store, flags: Pkcs7Flags, check_udid: bool, ) -> Result<(String, String, u32, String), Box<dyn Error>>113 fn parse_pkcs7_data(
114 pkcs7: &Pkcs7,
115 root_store: &X509Store,
116 flags: Pkcs7Flags,
117 check_udid: bool,
118 ) -> Result<(String, String, u32, String), Box<dyn Error>> {
119 let profile = verify_pkcs7_signature(pkcs7, root_store, flags)?;
120 let profile_json = parse_and_validate_profile(profile, check_udid)?;
121 get_cert_details(&profile_json)
122 }
123
verify_pkcs7_signature( pkcs7: &Pkcs7, root_store: &X509Store, flags: Pkcs7Flags, ) -> Result<Vec<u8>, Box<dyn Error>>124 fn verify_pkcs7_signature(
125 pkcs7: &Pkcs7,
126 root_store: &X509Store,
127 flags: Pkcs7Flags,
128 ) -> Result<Vec<u8>, Box<dyn Error>> {
129 let stack_of_certs = Stack::<X509>::new()?;
130 let mut profile = Vec::new();
131 pkcs7.verify(&stack_of_certs, root_store, None, Some(&mut profile), flags)?;
132 Ok(profile)
133 }
134
135 /// validate bundle info and debug info
validate_bundle_and_distribution_type( profile_json: &JsonValue, check_udid: bool, ) -> Result<(), Box<dyn Error>>136 pub fn validate_bundle_and_distribution_type(
137 profile_json: &JsonValue,
138 check_udid: bool,
139 ) -> Result<(), Box<dyn Error>> {
140 let bundle_type = profile_json[PROFILE_TYPE_KEY].try_as_string()?.as_str();
141 match bundle_type {
142 PROFILE_DEBUG_TYPE => {
143 if check_udid && verify_udid(profile_json).is_err() {
144 return Err("Invalid UDID.".into());
145 }
146 },
147 PROFILE_RELEASE_TYPE => {
148 let distribution_type = profile_json[PROFILE_APP_DISTRIBUTION_TYPE_KEY].try_as_string()?.as_str();
149 match distribution_type {
150 APP_DISTRIBUTION_TYPE_INTERNALTESTING => {
151 if check_udid && verify_udid(profile_json).is_err() {
152 return Err("Invalid UDID.".into());
153 }
154 },
155 APP_DISTRIBUTION_TYPE_ENTERPRISE |
156 APP_DISTRIBUTION_TYPE_ENTERPRISE_NORMAL |
157 APP_DISTRIBUTION_TYPE_ENTERPRISE_MDM => {
158 },
159 _ => {
160 return Err("Invalid app distribution type.".into());
161 }
162 }
163 }
164 _ => {
165 return Err("Invalid bundle type.".into());
166 },
167 }
168 Ok(())
169 }
170
parse_and_validate_profile( profile: Vec<u8>, check_udid: bool, ) -> Result<JsonValue, Box<dyn Error>>171 fn parse_and_validate_profile(
172 profile: Vec<u8>,
173 check_udid: bool,
174 ) -> Result<JsonValue, Box<dyn Error>> {
175 let profile_json = JsonValue::from_text(profile)?;
176 validate_bundle_and_distribution_type(&profile_json, check_udid)?;
177 Ok(profile_json)
178 }
179
get_cert_details(profile_json: &JsonValue) -> Result<(String, String, u32, String), Box<dyn Error>>180 fn get_cert_details(profile_json: &JsonValue) -> Result<(String, String, u32, String), Box<dyn Error>> {
181 let bundle_type = profile_json[PROFILE_TYPE_KEY].try_as_string()?.as_str();
182 let profile_type = match bundle_type {
183 PROFILE_DEBUG_TYPE => DebugCertPathType::Developer as u32,
184 PROFILE_RELEASE_TYPE => ReleaseCertPathType::Developer as u32,
185 _ => return Err("Invalid bundle type.".into()),
186 };
187 let app_id = match profile_json[PROFILE_BUNDLE_INFO_KEY][PROFILE_APP_IDENTIFIER_KEY] {
188 JsonValue::Null => EMPTY_APP_ID.to_string(),
189 _ => profile_json[PROFILE_BUNDLE_INFO_KEY][PROFILE_APP_IDENTIFIER_KEY].try_as_string()?.to_string(),
190 };
191 let signed_cert = match bundle_type {
192 PROFILE_DEBUG_TYPE => profile_json[PROFILE_BUNDLE_INFO_KEY][PROFILE_BUNDLE_INFO_DEBUG_KEY].try_as_string()?,
193 PROFILE_RELEASE_TYPE => profile_json[PROFILE_BUNDLE_INFO_KEY][PROFILE_BUNDLE_INFO_RELEASE_KEY].try_as_string()?,
194 _ => return Err("Invalid bundle type.".into()),
195 };
196 let signed_pem = X509::from_pem(signed_cert.as_bytes())?;
197 let subject = format_x509_fabricate_name(signed_pem.subject_name());
198 let issuer = format_x509_fabricate_name(signed_pem.issuer_name());
199 Ok((subject, issuer, profile_type, app_id))
200 }
201
202 lazy_static! {
203 /// global udid
204 pub static ref UDID: Result<String, String> = init_udid();
205 }
206
init_udid() -> Result<String, String>207 fn init_udid() -> Result<String, String> {
208 let mut udid: Vec<u8> = vec![0; 128];
209 let result = unsafe { CodeSignGetUdid(udid.as_mut_ptr()) };
210
211 if result != 0 {
212 return Err("Failed to get UDID".to_string());
213 }
214
215 if let Some(first_zero_index) = udid.iter().position(|&x| x == 0) {
216 udid.truncate(first_zero_index);
217 }
218
219 match String::from_utf8(udid) {
220 Ok(s) => Ok(s),
221 Err(_) => Err("UDID is not valid UTF-8".to_string()),
222 }
223 }
224
225 /// get device udid
get_udid() -> Result<String, String>226 pub fn get_udid() -> Result<String, String> {
227 UDID.clone()
228 }
229
230
verify_signers( pkcs7: &Pkcs7, profile_signer: &[(&String, &String)], ) -> Result<(), Box<dyn Error>>231 fn verify_signers(
232 pkcs7: &Pkcs7,
233 profile_signer: &[(&String, &String)],
234 ) -> Result<(), Box<dyn Error>> {
235 let stack_of_certs = Stack::<X509>::new()?;
236 let signers_result = pkcs7.signers(&stack_of_certs, Pkcs7Flags::empty())?;
237 for signer in signers_result {
238 let subject_name = format_x509name_to_string(signer.subject_name());
239 let issuer_name = format_x509name_to_string(signer.issuer_name());
240 if !profile_signer.contains(&(&subject_name, &issuer_name)) {
241 return Err("Verification failed.".into());
242 }
243 }
244 Ok(())
245 }
246
format_x509name_to_string(name: &X509NameRef) -> String247 fn format_x509name_to_string(name: &X509NameRef) -> String {
248 let mut parts = Vec::new();
249
250 for entry in name.entries() {
251 let tag = match entry.object().nid() {
252 openssl::nid::Nid::COMMONNAME => "CN",
253 openssl::nid::Nid::COUNTRYNAME => "C",
254 openssl::nid::Nid::ORGANIZATIONNAME => "O",
255 openssl::nid::Nid::ORGANIZATIONALUNITNAME => "OU",
256 _ => continue,
257 };
258 let value = entry.data().as_utf8().unwrap();
259 parts.push(format!("{}={}", tag, value));
260 }
261 parts.join(", ")
262 }
263
format_x509_fabricate_name(name: &X509NameRef) -> String264 fn format_x509_fabricate_name(name: &X509NameRef) -> String {
265 let mut common_name = String::new();
266 let mut organization = String::new();
267 let mut email = String::new();
268
269 for entry in name.entries() {
270 let entry_nid = entry.object().nid();
271 if let Ok(value) = entry.data().as_utf8() {
272 match entry_nid {
273 openssl::nid::Nid::COMMONNAME => common_name = value.to_string(),
274 openssl::nid::Nid::ORGANIZATIONNAME => organization = value.to_string(),
275 openssl::nid::Nid::PKCS9_EMAILADDRESS => email = value.to_string(),
276 _ => continue,
277 };
278 }
279 }
280 let ret = common_format_fabricate_name(&common_name, &organization, &email);
281 ret
282 }
283
get_profile_paths(is_debug: bool) -> Vec<String>284 fn get_profile_paths(is_debug: bool) -> Vec<String> {
285 let mut paths = Vec::new();
286 let profile_prefixes = match is_debug {
287 false => vec![PROFILE_STORE_EL0_PREFIX, PROFILE_STORE_EL1_PREFIX, PROFILE_STORE_EL1_PUBLIC_PREFIX],
288 true => vec![DEBUG_PROFILE_STORE_EL0_PREFIX, DEBUG_PROFILE_STORE_EL1_PREFIX, DEBUG_PROFILE_STORE_EL1_PUBLIC_PREFIX],
289 };
290 for profile_prefix in profile_prefixes {
291 paths.extend(get_paths_from_prefix(profile_prefix));
292 }
293 paths
294 }
295
get_paths_from_prefix(prefix: &str) -> Vec<String>296 fn get_paths_from_prefix(prefix: &str) -> Vec<String> {
297 let mut paths = Vec::new();
298 if let Ok(entries) = read_dir(prefix) {
299 for entry in entries.filter_map(Result::ok) {
300 let path = entry.path();
301 let filename = fmt_store_path(&path.to_string_lossy(), PROFILE_STORE_TAIL);
302 if file_exists(&filename) {
303 paths.push(filename);
304 }
305 }
306 }
307 paths
308 }
309
310 /// add profile cert path data
add_profile_cert_path( root_cert: &PemCollection, cert_paths: &TrustCertPath, ) -> Result<(), ProfileError>311 pub fn add_profile_cert_path(
312 root_cert: &PemCollection,
313 cert_paths: &TrustCertPath,
314 ) -> Result<(), ProfileError> {
315 let x509_store = root_cert.to_x509_store().unwrap();
316 if process_profile(false, &x509_store, cert_paths.get_profile_info().as_slice()).is_err() {
317 return Err(ProfileError::AddCertPathError);
318 }
319 if process_profile(true, &x509_store, cert_paths.get_debug_profile_info().as_slice()).is_err() {
320 return Err(ProfileError::AddCertPathError);
321 }
322 Ok(())
323 }
324
process_profile( is_debug: bool, x509_store: &X509Store, profile_info: &[(&String, &String)], ) -> Result<(), ProfileError>325 fn process_profile(
326 is_debug: bool,
327 x509_store: &X509Store,
328 profile_info: &[(&String, &String)],
329 ) -> Result<(), ProfileError> {
330 let profiles_paths = get_profile_paths(is_debug);
331 for path in profiles_paths {
332 let mut pkcs7_data = Vec::new();
333 if load_bytes_from_file(&path, &mut pkcs7_data).is_err() {
334 error!(LOG_LABEL, "load profile failed {}!", @public(path));
335 continue;
336 }
337 info!(LOG_LABEL, "load profile success {}!", @public(path));
338 let pkcs7 = match Pkcs7::from_der(&pkcs7_data) {
339 Ok(pk7) => pk7,
340 Err(_) => {
341 error!(LOG_LABEL, "load profile to pkcs7 obj failed {}!", @public(path));
342 continue;
343 }
344 };
345 if verify_signers(&pkcs7, profile_info).is_err() {
346 error!(LOG_LABEL, "Invalid signer profile file {}", @public(path));
347 report_parse_profile_err(&path, HisyseventProfileError::VerifySigner as i32);
348 continue;
349 }
350 let check_udid = unsafe { !IsRdDevice() };
351 let (subject, issuer, profile_type, app_id) =
352 match parse_pkcs7_data(&pkcs7, x509_store, Pkcs7Flags::empty(), check_udid) {
353 Ok(tuple) => tuple,
354 Err(e) => {
355 error!(LOG_LABEL, "Error parsing PKCS7 data: {}, profile file {}",
356 @public(e), @public(path));
357 report_parse_profile_err(&path, HisyseventProfileError::ParsePkcs7 as i32);
358 continue;
359 }
360 };
361 if add_cert_path_info(subject, issuer, profile_type, app_id, DEFAULT_MAX_CERT_PATH_LEN).is_err() {
362 error!(
363 LOG_LABEL,
364 "Failed to add profile cert path info into ioctl for {}", @public(path)
365 );
366 report_parse_profile_err(&path, HisyseventProfileError::AddCertPath as i32);
367 continue;
368 }
369 }
370 Ok(())
371 }
372
verify_udid(profile_json: &JsonValue) -> Result<(), String>373 fn verify_udid(profile_json: &JsonValue) -> Result<(), String> {
374 let device_udid = get_udid()?;
375 info!(LOG_LABEL, "get device udid {}!", device_udid);
376 let device_id_type = &profile_json[PROFILE_DEBUG_INFO_KEY][PROFILE_DEVICE_ID_TYPE_KEY];
377
378 if let JsonValue::String(id_type) = device_id_type {
379 if id_type != "udid" {
380 return Err("Invalid device ID type".to_string());
381 }
382 } else {
383 return Err("Device ID type is not a string".to_string());
384 }
385 match &profile_json[PROFILE_DEBUG_INFO_KEY][PROFILE_DEVICE_IDS_KEY] {
386 JsonValue::Array(arr) => {
387 if arr.iter().any(|item| match item {
388 JsonValue::String(s) => s == &device_udid,
389 _ => false,
390 }) {
391 Ok(())
392 } else {
393 Err("UDID not found in the list".to_string())
394 }
395 }
396 _ => Err("Device IDs are not in an array format".to_string()),
397 }
398 }
399
validate_and_convert_inputs( bundle_name: *const c_char, profile: *const u8, profile_size: u32, ) -> Result<(String, Vec<u8>), ()>400 fn validate_and_convert_inputs(
401 bundle_name: *const c_char,
402 profile: *const u8,
403 profile_size: u32,
404 ) -> Result<(String, Vec<u8>), ()> {
405 let _bundle_name = c_char_to_string(bundle_name);
406 if _bundle_name.is_empty() {
407 error!(LOG_LABEL, "invalid profile bundle name!");
408 return Err(());
409 }
410 let profile_data = cbyte_buffer_to_vec(profile, profile_size);
411 Ok((_bundle_name, profile_data))
412 }
413
process_data(profile_data: &[u8]) -> Result<(String, String, u32, String), ()>414 fn process_data(profile_data: &[u8]) -> Result<(String, String, u32, String), ()> {
415 let store = match X509StoreBuilder::new() {
416 Ok(store) => store.build(),
417 Err(_) => {
418 error!(LOG_LABEL, "Failed to build X509 store");
419 return Err(());
420 }
421 };
422
423 let pkcs7 = match Pkcs7::from_der(profile_data) {
424 Ok(pk7) => pk7,
425 Err(_) => {
426 error!(LOG_LABEL, "load profile to pkcs7 obj failed");
427 return Err(());
428 }
429 };
430
431 match parse_pkcs7_data(&pkcs7, &store, Pkcs7Flags::NOVERIFY, false) {
432 Ok(tuple) => Ok(tuple),
433 Err(_) => {
434 error!(LOG_LABEL, "parse pkcs7 data error");
435 Err(())
436 }
437 }
438 }
439
create_bundle_path(bundle_name: &str, profile_type: u32) -> Result<String, ()>440 fn create_bundle_path(bundle_name: &str, profile_type: u32) -> Result<String, ()> {
441 let bundle_path = match profile_type {
442 value if value == DebugCertPathType::Developer as u32 => {
443 fmt_store_path(DEBUG_PROFILE_STORE_EL1_PUBLIC_PREFIX, bundle_name)
444 }
445 value if value == ReleaseCertPathType::Developer as u32 => {
446 fmt_store_path(PROFILE_STORE_EL1_PUBLIC_PREFIX, bundle_name)
447 }
448 _ => {
449 error!(LOG_LABEL, "invalid profile type");
450 return Err(());
451 }
452 };
453 Ok(bundle_path)
454 }
455
enable_key_in_profile_internal( bundle_name: *const c_char, profile: *const u8, profile_size: u32, ) -> Result<(), ()>456 fn enable_key_in_profile_internal(
457 bundle_name: *const c_char,
458 profile: *const u8,
459 profile_size: u32,
460 ) -> Result<(), ()> {
461 let (_bundle_name, profile_data) = validate_and_convert_inputs(bundle_name, profile, profile_size)?;
462 let (subject, issuer, profile_type, app_id) = process_data(&profile_data)?;
463 let bundle_path = create_bundle_path(&_bundle_name, profile_type)?;
464 info!(LOG_LABEL, "create bundle_path path {}!", @public(bundle_path));
465 if !file_exists(&bundle_path) && create_file_path(&bundle_path).is_err() {
466 error!(LOG_LABEL, "create bundle_path path {} failed!", @public(bundle_path));
467 return Err(());
468 }
469 if change_default_mode_directory(&bundle_path).is_err() {
470 error!(LOG_LABEL, "change bundle_path mode error!");
471 return Err(());
472 }
473 let filename = fmt_store_path(&bundle_path, PROFILE_STORE_TAIL);
474 if write_bytes_to_file(&filename, &profile_data).is_err() {
475 error!(LOG_LABEL, "dump profile data error!");
476 return Err(());
477 }
478 if change_default_mode_file(&filename).is_err() {
479 error!(LOG_LABEL, "change profile mode error!");
480 return Err(());
481 }
482 if add_cert_path_info(subject, issuer, profile_type, app_id, DEFAULT_MAX_CERT_PATH_LEN).is_err() {
483 error!(LOG_LABEL, "add profile data error!");
484 return Err(());
485 }
486 info!(LOG_LABEL, "finish add cert path in ioctl!");
487 Ok(())
488 }
489
process_remove_bundle( prefix: &str, bundle_name: &str, ) -> Result<(), ()>490 fn process_remove_bundle(
491 prefix: &str,
492 bundle_name: &str,
493 ) -> Result<(), ()> {
494 let bundle_path = fmt_store_path(prefix, bundle_name);
495
496 if !file_exists(&bundle_path) {
497 return Err(());
498 }
499
500 let filename = fmt_store_path(&bundle_path, PROFILE_STORE_TAIL);
501 let mut profile_data = Vec::new();
502 if load_bytes_from_file(&filename, &mut profile_data).is_err() {
503 error!(LOG_LABEL, "load profile data error!");
504 return Err(());
505 }
506
507 let (subject, issuer, profile_type, app_id) = process_data(&profile_data)?;
508 if delete_file_path(&bundle_path).is_err() {
509 error!(LOG_LABEL, "remove profile data error!");
510 return Err(());
511 }
512
513 info!(LOG_LABEL, "remove bundle_path path {}!", @public(bundle_path));
514
515 if remove_cert_path_info(subject, issuer, profile_type, app_id, DEFAULT_MAX_CERT_PATH_LEN).is_err() {
516 error!(LOG_LABEL, "remove profile data error!");
517 return Err(());
518 }
519
520 info!(LOG_LABEL, "finish remove cert path in ioctl!");
521 Ok(())
522 }
523
remove_key_in_profile_internal(bundle_name: *const c_char) -> Result<(), ()>524 fn remove_key_in_profile_internal(bundle_name: *const c_char) -> Result<(), ()> {
525 let _bundle_name = c_char_to_string(bundle_name);
526 if _bundle_name.is_empty() {
527 error!(LOG_LABEL, "Invalid bundle name");
528 return Err(());
529 }
530
531 let profile_prefix = vec![
532 DEBUG_PROFILE_STORE_EL0_PREFIX,
533 PROFILE_STORE_EL0_PREFIX,
534 DEBUG_PROFILE_STORE_EL1_PREFIX,
535 PROFILE_STORE_EL1_PREFIX,
536 DEBUG_PROFILE_STORE_EL1_PUBLIC_PREFIX,
537 PROFILE_STORE_EL1_PUBLIC_PREFIX,
538 ];
539
540 let mut rm_succ = false;
541 for prefix in profile_prefix {
542 if process_remove_bundle(prefix, &_bundle_name).is_ok() {
543 rm_succ = true;
544 }
545 }
546 if rm_succ {
547 Ok(())
548 } else {
549 error!(LOG_LABEL, "Failed to remove bundle profile info, bundleName: {}.", @public(_bundle_name));
550 Err(())
551 }
552 }
553
c_char_to_string(c_str: *const c_char) -> String554 fn c_char_to_string(c_str: *const c_char) -> String {
555 unsafe {
556 if c_str.is_null() {
557 return String::new();
558 }
559 let c_str = CStr::from_ptr(c_str);
560 c_str.to_string_lossy().to_string()
561 }
562 }
563
cbyte_buffer_to_vec(data: *const u8, size: u32) -> Vec<u8>564 fn cbyte_buffer_to_vec(data: *const u8, size: u32) -> Vec<u8> {
565 unsafe {
566 if data.is_null() {
567 return Vec::new();
568 }
569 let data_slice = std::slice::from_raw_parts(data, size as usize);
570 let mut result = Vec::with_capacity(size as usize);
571 result.extend_from_slice(data_slice);
572 result
573 }
574 }
575