Merge pull request #2 from hugeBlack/main

put p12 cert into sidestore's bundle when installing.
This commit is contained in:
Nicholas Sharp
2025-11-20 21:53:41 -05:00
committed by GitHub
3 changed files with 58 additions and 4 deletions

View File

@@ -3,6 +3,7 @@
use hex; use hex;
use openssl::{ use openssl::{
hash::MessageDigest, hash::MessageDigest,
pkcs12::Pkcs12,
pkey::{PKey, Private}, pkey::{PKey, Private},
rsa::Rsa, rsa::Rsa,
x509::{X509, X509Name, X509ReqBuilder}, x509::{X509, X509Name, X509ReqBuilder},
@@ -23,6 +24,7 @@ pub struct CertificateIdentity {
pub key_file: PathBuf, pub key_file: PathBuf,
pub cert_file: PathBuf, pub cert_file: PathBuf,
pub machine_name: String, pub machine_name: String,
pub machine_id: String,
} }
impl CertificateIdentity { impl CertificateIdentity {
@@ -67,14 +69,15 @@ impl CertificateIdentity {
key_file, key_file,
cert_file, cert_file,
machine_name, machine_name,
machine_id: "".to_owned(),
}; };
if let Ok(cert) = cert_identity if let Ok((cert, machine_id)) = cert_identity
.find_matching_certificate(dev_session, team) .find_matching_certificate(dev_session, team)
.await .await
{ {
cert_identity.certificate = Some(cert.clone()); cert_identity.certificate = Some(cert.clone());
cert_identity.machine_id = machine_id;
let cert_pem = cert.to_pem().map_err(|e| { let cert_pem = cert.to_pem().map_err(|e| {
Error::Certificate(format!("Failed to encode certificate to PEM: {}", e)) Error::Certificate(format!("Failed to encode certificate to PEM: {}", e))
})?; })?;
@@ -93,7 +96,7 @@ impl CertificateIdentity {
&self, &self,
dev_session: &DeveloperSession, dev_session: &DeveloperSession,
team: &DeveloperTeam, team: &DeveloperTeam,
) -> Result<X509, Error> { ) -> Result<(X509, String), Error> {
let certificates = dev_session let certificates = dev_session
.list_all_development_certs(DeveloperDeviceType::Ios, team) .list_all_development_certs(DeveloperDeviceType::Ios, team)
.await .await
@@ -113,7 +116,7 @@ impl CertificateIdentity {
&& let Ok(cert_public_key_der) = cert_public_key.public_key_to_der() && let Ok(cert_public_key_der) = cert_public_key.public_key_to_der()
&& cert_public_key_der == our_public_key && cert_public_key_der == our_public_key
{ {
return Ok(x509_cert); return Ok((x509_cert, cert.machine_id.clone()));
} }
} }
Err(Error::Certificate( Err(Error::Certificate(
@@ -203,6 +206,7 @@ impl CertificateIdentity {
fs::write(&self.cert_file, cert_pem).map_err(Error::Filesystem)?; fs::write(&self.cert_file, cert_pem).map_err(Error::Filesystem)?;
self.certificate = Some(certificate); self.certificate = Some(certificate);
self.machine_id = apple_cert.machine_id.clone();
Ok(()) Ok(())
} }
@@ -241,4 +245,29 @@ impl CertificateIdentity {
Ok(num.trim_start_matches("0").to_string()) Ok(num.trim_start_matches("0").to_string())
} }
pub fn to_pkcs12(&self, password: &str) -> Result<Vec<u8>, Error> {
let cert = match &self.certificate {
Some(c) => c,
None => {
return Err(Error::Certificate(
"No certificate available to create PKCS#12".to_string(),
));
}
};
let mut pkcs12_builder = Pkcs12::builder();
pkcs12_builder.pkey(&self.private_key);
pkcs12_builder.cert(cert);
pkcs12_builder.name("certificate");
let pkcs12 = pkcs12_builder
.build2(password)
.map_err(|e| Error::Certificate(format!("Failed to create PKCS#12 bundle: {}", e)))?;
let der_bytes = pkcs12
.to_der()
.map_err(|e| Error::Certificate(format!("Failed to encode PKCS#12 to DER: {}", e)))?;
Ok(der_bytes)
}
} }

View File

@@ -257,6 +257,11 @@ impl DeveloperSession {
.and_then(|v| v.as_string()) .and_then(|v| v.as_string())
.unwrap_or("") .unwrap_or("")
.to_string(); .to_string();
let machine_id = dict
.get("machineId")
.and_then(|v| v.as_string())
.ok_or(Error::Parse("machineId".to_string()))?
.to_string();
let cert_content = dict let cert_content = dict
.get("certContent") .get("certContent")
.and_then(|v| v.as_data()) .and_then(|v| v.as_data())
@@ -268,6 +273,7 @@ impl DeveloperSession {
certificate_id, certificate_id,
serial_number, serial_number,
machine_name, machine_name,
machine_id,
cert_content, cert_content,
}); });
} }
@@ -685,6 +691,7 @@ pub struct DevelopmentCertificate {
pub certificate_id: String, pub certificate_id: String,
pub serial_number: String, pub serial_number: String,
pub machine_name: String, pub machine_name: String,
pub machine_id: String,
pub cert_content: Vec<u8>, pub cert_content: Vec<u8>,
} }

View File

@@ -259,6 +259,24 @@ pub async fn sideload_app(
"ALTAppGroups".to_string(), "ALTAppGroups".to_string(),
plist::Value::Array(vec![plist::Value::String(group_identifier.clone())]), plist::Value::Array(vec![plist::Value::String(group_identifier.clone())]),
); );
app.bundle.app_info.insert(
"ALTCertificateID".to_string(),
plist::Value::String(cert.get_serial_number().unwrap()),
);
match cert.to_pkcs12(&cert.machine_id) {
Ok(p12_bytes) => {
let alt_cert_path = app.bundle.bundle_dir.join("ALTCertificate.p12");
if alt_cert_path.exists() {
std::fs::remove_file(&alt_cert_path).map_err(Error::Filesystem)?;
}
let mut file = std::fs::File::create(&alt_cert_path).map_err(Error::Filesystem)?;
file.write_all(&p12_bytes).map_err(Error::Filesystem)?;
}
Err(e) => return error_and_return(logger, e),
}
} }
let app_groups = match dev_session let app_groups = match dev_session