Modify bundle for altstore/sidestore/sidstore+lc

This commit is contained in:
nab138
2026-02-13 09:01:33 -05:00
parent d007f259c1
commit 59985f9b92
4 changed files with 71 additions and 4 deletions

View File

@@ -14,7 +14,6 @@ readme = "../README.md"
default = ["install", "keyring-storage"]
install = ["dep:idevice"]
keyring-storage = ["keyring"]
p12 = ["dep:p12-keystore"]
# Unfortunately, dependencies are kinda a mess rn, since this requires a beta version of the srp crate.
# Once that becomes stable, hopefuly duplicate dependencies should clean up.\
@@ -44,10 +43,10 @@ cbc = { version = "0.2.0-rc.3", features = ["alloc"] }
aes = "0.9.0-rc.4"
aes-gcm = "0.11.0-rc.3"
rsa = { version = "0.10.0-rc.15" }
tokio = "1.49.0"
tokio = { version = "1.49.0", features = ["fs"] }
keyring = { version = "3.6.3", features = ["apple-native", "linux-native-sync-persistent", "windows-native"], optional = true }
# TODO: Fork to update dependencies (doubt it will ever be updated)
x509-certificate = "0.25"
rcgen = { version = "0.14.7", default-features = false, features = ["aws_lc_rs", "pem"] }
p12-keystore = { optional = true, version = "0.2.0" }
p12-keystore = "0.2.0"
zip = { version = "7.4", default-features = false, features = ["deflate"] }

View File

@@ -7,10 +7,12 @@ use crate::dev::developer_session::DeveloperSession;
use crate::dev::teams::DeveloperTeam;
use crate::sideload::builder::ExtensionsBehavior;
use crate::sideload::bundle::Bundle;
use crate::sideload::cert_identity::CertificateIdentity;
use rootcause::option_ext::OptionExt;
use rootcause::prelude::*;
use std::fs::File;
use std::path::PathBuf;
use tokio::io::AsyncWriteExt;
use zip::ZipArchive;
pub struct Application {
@@ -206,6 +208,57 @@ impl Application {
Ok(app_ids)
}
pub async fn apply_special_app_behavior(
&mut self,
special: &Option<SpecialApp>,
group_identifier: &str,
cert: &CertificateIdentity,
) -> Result<(), Report> {
if special.is_none() {
return Ok(());
}
let special = special.as_ref().unwrap();
if special == &SpecialApp::SideStoreLc
|| special == &SpecialApp::SideStore
|| special == &SpecialApp::AltStore
{
self.bundle.app_info.insert(
"ALTAppGroups".to_string(),
plist::Value::Array(vec![plist::Value::String(group_identifier.to_string())]),
);
let target_bundle =
match special {
SpecialApp::SideStoreLc => self.bundle.frameworks_mut().iter_mut().find(|fw| {
fw.bundle_identifier().unwrap_or("") == "com.SideStore.SideStore"
}),
_ => Some(&mut self.bundle),
};
if let Some(target_bundle) = target_bundle {
target_bundle.app_info.insert(
"ALTCertificateID".to_string(),
plist::Value::String(cert.get_serial_number()),
);
let p12_bytes = cert
.as_p12(&cert.machine_id)
.await
.context("Failed to encode cert as p12")?;
let alt_cert_path = target_bundle.bundle_dir.join("ALTCertificate.p12");
let mut file = tokio::fs::File::create(&alt_cert_path)
.await
.context("Failed to create ALTCertificate.p12")?;
file.write_all(&p12_bytes)
.await
.context("Failed to write ALTCertificate.p12")?;
}
}
Ok(())
}
}
#[derive(Debug, Clone, PartialEq, Eq)]

View File

@@ -1,3 +1,4 @@
use hex::ToHex;
use rcgen::{CertificateParams, DistinguishedName, DnType, KeyPair, PKCS_RSA_SHA256};
use rootcause::prelude::*;
use rsa::{
@@ -31,7 +32,6 @@ pub struct CertificateIdentity {
impl CertificateIdentity {
// This implementation was "heavily inspired" by Impactor (https://github.com/khcrysalis/Impactor/blob/main/crates/plume_core/src/utils/certificate.rs)
// It's a little messy and I will clean it up when the rust crypto ecosystem gets through it's next release cycle and I can reduce duplicate dependencies
#[cfg(feature = "p12")]
/// Exports the certificate and private key as a PKCS#12 archive
/// If you plan to import into SideStore/AltStore, use the machine id as the password
pub async fn as_p12(&self, password: &str) -> Result<Vec<u8>, Report> {
@@ -61,6 +61,10 @@ impl CertificateIdentity {
Ok(p12)
}
pub fn get_serial_number(&self) -> String {
self.certificate.serial_number_asn1().encode_hex()
}
pub async fn retrieve(
machine_name: &str,
apple_email: &str,

View File

@@ -129,11 +129,22 @@ impl Sideloader {
// TODO: Increased memory entitlement
}
app.apply_special_app_behavior(&special, &group_identifier, &cert_identity)
.await?;
let provisioning_profile = self
.dev_session
.download_team_provisioning_profile(&team, &main_app_id, None)
.await?;
app.bundle.write_info()?;
for ext in app.bundle.app_extensions_mut() {
ext.write_info()?;
}
for ext in app.bundle.frameworks_mut() {
ext.write_info()?;
}
Ok(())
}