Improve error handling and fix compilation errors

This commit is contained in:
nab138
2025-08-06 22:13:57 -04:00
parent 9baf77f00e
commit e94d7b6448
6 changed files with 98 additions and 63 deletions

41
Cargo.lock generated
View File

@@ -677,6 +677,21 @@ version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
[[package]]
name = "futures"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876"
dependencies = [
"futures-channel",
"futures-core",
"futures-executor",
"futures-io",
"futures-sink",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-channel"
version = "0.3.31"
@@ -684,6 +699,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
dependencies = [
"futures-core",
"futures-sink",
]
[[package]]
@@ -692,6 +708,17 @@ version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
[[package]]
name = "futures-executor"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f"
dependencies = [
"futures-core",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-io"
version = "0.3.31"
@@ -727,6 +754,7 @@ version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
dependencies = [
"futures-channel",
"futures-core",
"futures-io",
"futures-macro",
@@ -1061,6 +1089,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b9d40e2753062fba4cac48cb459987dd9f66f6b777d90c546548f053bdd03c0"
dependencies = [
"base64 0.22.1",
"chrono",
"env_logger",
"log",
"plist",
@@ -1139,9 +1168,11 @@ checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
name = "isideload"
version = "0.1.0"
dependencies = [
"futures",
"hex",
"icloud_auth",
"idevice",
"openssl",
"plist",
"serde",
"sha1",
@@ -1531,6 +1562,15 @@ version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
[[package]]
name = "openssl-src"
version = "300.5.1+3.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "735230c832b28c000e3bc117119e6466a663ec73506bc0a9907ea4187508e42a"
dependencies = [
"cc",
]
[[package]]
name = "openssl-sys"
version = "0.9.109"
@@ -1539,6 +1579,7 @@ checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571"
dependencies = [
"cc",
"libc",
"openssl-src",
"pkg-config",
"vcpkg",
]

View File

@@ -3,6 +3,11 @@ name = "isideload"
version = "0.1.0"
edition = "2024"
[features]
default = []
vendored-openssl = ["openssl/vendored"]
vendored-botan = ["icloud_auth/vendored-botan"]
[dependencies]
serde = { version = "1.0.219", features = ["derive"] }
plist = { version = "1.7.2" }
@@ -11,4 +16,6 @@ uuid = "1.17.0"
zip = "4.3.0"
hex = "0.4.3"
sha1 = "0.10.6"
idevice = "0.1.37"
idevice = { version = "0.1.37", features = ["afc", "usbmuxd", "installation_proxy"] }
openssl = "0.10.73"
futures = "0.3.31"

View File

@@ -3,7 +3,9 @@ name = "icloud_auth"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[features]
default = []
vendored-botan = ["botan/vendored"]
[dependencies]
serde = { version = "1.0.219", features = ["derive"] }
@@ -25,7 +27,7 @@ reqwest = { version = "0.11.14", features = ["blocking", "json", "default-tls"]
omnisette = {path = "../omnisette", features = ["remote-anisette-v3"]}
thiserror = "1.0.58"
tokio = "1"
botan = { version = "0.11.1", features = ["vendored"] }
botan = { version = "0.11.1" }
chrono = { version = "0.4", features = ["serde"] }
[dev-dependencies]

View File

@@ -32,30 +32,29 @@ impl CertificateIdentity {
let hash_string = hex::encode(hasher.finalize()).to_lowercase();
let key_path = configuration_path.join("keys").join(hash_string);
fs::create_dir_all(&key_path)
.map_err(|e| format!("Failed to create key directory: {}", e))?;
.map_err(|e| Error::Certificate(format!("Failed to create key directory: {}", e)))?;
let key_file = key_path.join("key.pem");
let cert_file = key_path.join("cert.pem");
let teams = dev_session
.list_teams()
.await
.map_err(|e| format!("Failed to list teams: {:?}", e))?;
let team = teams.first().ok_or("No teams found")?;
let teams = dev_session.list_teams().await?;
let team = teams
.first()
.ok_or(Error::Certificate("No teams found".to_string()))?;
let private_key = if key_file.exists() {
let key_data = fs::read_to_string(&key_file)
.map_err(|e| format!("Failed to read key file: {}", e))?;
.map_err(|e| Error::Certificate(format!("Failed to read key file: {}", e)))?;
PKey::private_key_from_pem(key_data.as_bytes())
.map_err(|e| format!("Failed to load private key: {}", e))?
.map_err(|e| Error::Certificate(format!("Failed to load private key: {}", e)))?
} else {
let rsa =
Rsa::generate(2048).map_err(|e| format!("Failed to generate RSA key: {}", e))?;
let key =
PKey::from_rsa(rsa).map_err(|e| format!("Failed to create private key: {}", e))?;
let rsa = Rsa::generate(2048)
.map_err(|e| Error::Certificate(format!("Failed to generate RSA key: {}", e)))?;
let key = PKey::from_rsa(rsa)
.map_err(|e| Error::Certificate(format!("Failed to create private key: {}", e)))?;
let pem_data = key
.private_key_to_pem_pkcs8()
.map_err(|e| format!("Failed to encode private key: {}", e))?;
.map_err(|e| Error::Certificate(format!("Failed to encode private key: {}", e)))?;
fs::write(&key_file, pem_data)
.map_err(|e| format!("Failed to save key file: {}", e))?;
.map_err(|e| Error::Certificate(format!("Failed to save key file: {}", e)))?;
key
};
@@ -72,11 +71,12 @@ impl CertificateIdentity {
{
cert_identity.certificate = Some(cert.clone());
let cert_pem = cert
.to_pem()
.map_err(|e| format!("Failed to encode certificate to PEM: {}", e))?;
fs::write(&cert_identity.cert_file, cert_pem)
.map_err(|e| format!("Failed to save certificate file: {}", e))?;
let cert_pem = cert.to_pem().map_err(|e| {
Error::Certificate(format!("Failed to encode certificate to PEM: {}", e))
})?;
fs::write(&cert_identity.cert_file, cert_pem).map_err(|e| {
Error::Certificate(format!("Failed to save certificate file: {}", e))
})?;
return Ok(cert_identity);
}
@@ -116,7 +116,9 @@ impl CertificateIdentity {
}
}
}
Error::Certificate("No matching certificate found".to_string())
Err(Error::Certificate(
"No matching certificate found".to_string(),
))
}
async fn request_new_certificate(
@@ -125,40 +127,40 @@ impl CertificateIdentity {
team: &DeveloperTeam,
) -> Result<(), Error> {
let mut req_builder = X509ReqBuilder::new()
.map_err(|e| format!("Failed to create request builder: {}", e))?;
let mut name_builder =
X509Name::builder().map_err(|e| format!("Failed to create name builder: {}", e))?;
.map_err(|e| Error::Certificate(format!("Failed to create request builder: {}", e)))?;
let mut name_builder = X509Name::builder()
.map_err(|e| Error::Certificate(format!("Failed to create name builder: {}", e)))?;
name_builder
.append_entry_by_text("C", "US")
.map_err(|e| format!("Failed to set country: {}", e))?;
.map_err(|e| Error::Certificate(format!("Failed to set country: {}", e)))?;
name_builder
.append_entry_by_text("ST", "STATE")
.map_err(|e| format!("Failed to set state: {}", e))?;
.map_err(|e| Error::Certificate(format!("Failed to set state: {}", e)))?;
name_builder
.append_entry_by_text("L", "LOCAL")
.map_err(|e| format!("Failed to set locality: {}", e))?;
.map_err(|e| Error::Certificate(format!("Failed to set locality: {}", e)))?;
name_builder
.append_entry_by_text("O", "ORGNIZATION")
.map_err(|e| format!("Failed to set organization: {}", e))?;
.map_err(|e| Error::Certificate(format!("Failed to set organization: {}", e)))?;
name_builder
.append_entry_by_text("CN", "CN")
.map_err(|e| format!("Failed to set common name: {}", e))?;
.map_err(|e| Error::Certificate(format!("Failed to set common name: {}", e)))?;
req_builder
.set_subject_name(&name_builder.build())
.map_err(|e| format!("Failed to set subject name: {}", e))?;
.map_err(|e| Error::Certificate(format!("Failed to set subject name: {}", e)))?;
req_builder
.set_pubkey(&self.private_key)
.map_err(|e| format!("Failed to set public key: {}", e))?;
.map_err(|e| Error::Certificate(format!("Failed to set public key: {}", e)))?;
req_builder
.sign(&self.private_key, MessageDigest::sha256())
.map_err(|e| format!("Failed to sign request: {}", e))?;
.map_err(|e| Error::Certificate(format!("Failed to sign request: {}", e)))?;
let csr_pem = req_builder
.build()
.to_pem()
.map_err(|e| format!("Failed to encode CSR: {}", e))?;
.map_err(|e| Error::Certificate(format!("Failed to encode CSR: {}", e)))?;
let certificate_id = dev_session
.submit_development_csr(
@@ -181,23 +183,24 @@ impl CertificateIdentity {
let certificates = dev_session
.list_all_development_certs(DeveloperDeviceType::Ios, team)
.await
.map_err(|e| format!("Failed to list certificates: {:?}", e))?;
.await?;
let apple_cert = certificates
.iter()
.find(|cert| cert.certificate_id == certificate_id)
.ok_or("Certificate not found after submission")?;
.ok_or(Error::Certificate(
"Certificate not found after submission".to_string(),
))?;
let certificate = X509::from_der(&apple_cert.cert_content)
.map_err(|e| format!("Failed to parse certificate: {}", e))?;
.map_err(|e| Error::Certificate(format!("Failed to parse certificate: {}", e)))?;
// Write certificate to disk
let cert_pem = certificate
.to_pem()
.map_err(|e| format!("Failed to encode certificate to PEM: {}", e))?;
let cert_pem = certificate.to_pem().map_err(|e| {
Error::Certificate(format!("Failed to encode certificate to PEM: {}", e))
})?;
fs::write(&self.cert_file, cert_pem)
.map_err(|e| format!("Failed to save certificate file: {}", e))?;
.map_err(|e| Error::Certificate(format!("Failed to save certificate file: {}", e)))?;
self.certificate = Some(certificate);

View File

@@ -160,20 +160,3 @@ fn afc_upload_dir<'a>(
Ok(())
})
}
#[tauri::command]
pub async fn refresh_idevice(window: tauri::Window) {
match list_devices().await {
Ok(devices) => {
window
.emit("idevices", devices)
.expect("Failed to send devices");
}
Err(e) => {
window
.emit("idevices", Vec::<DeviceInfo>::new())
.expect("Failed to send error");
eprintln!("Failed to list devices: {}", e);
}
};
}

View File

@@ -2,10 +2,9 @@
use crate::Error;
use crate::{
certificate::CertificateIdentity,
developer_session::DeveloperDeviceType,
device::{DeviceInfo, install_app},
sideloader::{
certificate::CertificateIdentity, developer_session::DeveloperDeviceType,
},
};
use std::{io::Write, path::PathBuf};