• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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