Add OpenSSL dependency

This commit is contained in:
Jackson Coxson
2025-11-15 11:45:34 -07:00
parent 13c5b48b1c
commit db894120da
6 changed files with 233 additions and 52 deletions

78
Cargo.lock generated
View File

@@ -672,6 +672,21 @@ version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "foreign-types"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
dependencies = [
"foreign-types-shared",
]
[[package]]
name = "foreign-types-shared"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
[[package]] [[package]]
name = "form_urlencoded" name = "form_urlencoded"
version = "1.2.2" version = "1.2.2"
@@ -1064,6 +1079,7 @@ dependencies = [
"json", "json",
"ns-keyed-archive", "ns-keyed-archive",
"obfstr", "obfstr",
"openssl",
"plist", "plist",
"rand 0.9.2", "rand 0.9.2",
"reqwest", "reqwest",
@@ -1074,6 +1090,7 @@ dependencies = [
"sha2", "sha2",
"thiserror 2.0.17", "thiserror 2.0.17",
"tokio", "tokio",
"tokio-openssl",
"tokio-rustls", "tokio-rustls",
"tracing", "tracing",
"tun-rs", "tun-rs",
@@ -1548,6 +1565,44 @@ version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad"
[[package]]
name = "openssl"
version = "0.10.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328"
dependencies = [
"bitflags",
"cfg-if",
"foreign-types",
"libc",
"once_cell",
"openssl-macros",
"openssl-sys",
]
[[package]]
name = "openssl-macros"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.106",
]
[[package]]
name = "openssl-sys"
version = "0.9.111"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321"
dependencies = [
"cc",
"libc",
"pkg-config",
"vcpkg",
]
[[package]] [[package]]
name = "parking" name = "parking"
version = "2.2.1" version = "2.2.1"
@@ -1662,6 +1717,12 @@ dependencies = [
"spki", "spki",
] ]
[[package]]
name = "pkg-config"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
[[package]] [[package]]
name = "plist" name = "plist"
version = "1.8.0" version = "1.8.0"
@@ -2404,6 +2465,17 @@ dependencies = [
"syn 2.0.106", "syn 2.0.106",
] ]
[[package]]
name = "tokio-openssl"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59df6849caa43bb7567f9a36f863c447d95a11d5903c9cc334ba32576a27eadd"
dependencies = [
"openssl",
"openssl-sys",
"tokio",
]
[[package]] [[package]]
name = "tokio-rustls" name = "tokio-rustls"
version = "0.26.4" version = "0.26.4"
@@ -2716,6 +2788,12 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"
[[package]]
name = "vcpkg"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]] [[package]]
name = "version_check" name = "version_check"
version = "0.9.5" version = "0.9.5"

View File

@@ -12,16 +12,18 @@ keywords = ["lockdownd", "ios"]
[dependencies] [dependencies]
tokio = { version = "1", features = ["io-util"] } tokio = { version = "1", features = ["io-util"] }
tokio-rustls = { version = "0.26", default-features = false } tokio-rustls = { version = "0.26", default-features = false, optional = true }
rustls = { version = "0.23", default-features = false, features = [ rustls = { version = "0.23", default-features = false, features = [
"std", "std",
"tls12", "tls12",
] } ], optional = true }
crossfire = { version = "2.1", optional = true } tokio-openssl = { version = "0.6", optional = true }
openssl = { version = "0.10", optional = true }
plist = { version = "1.8" } plist = { version = "1.8" }
serde = { version = "1", features = ["derive"] } serde = { version = "1", features = ["derive"] }
ns-keyed-archive = { version = "0.1.4", optional = true } ns-keyed-archive = { version = "0.1.4", optional = true }
crossfire = { version = "2.1", optional = true }
thiserror = { version = "2" } thiserror = { version = "2" }
tracing = { version = "0.1.41" } tracing = { version = "0.1.41" }
@@ -64,8 +66,10 @@ bytes = "1.10.1"
[features] [features]
default = ["aws-lc"] default = ["aws-lc"]
aws-lc = ["rustls/aws-lc-rs", "tokio-rustls/aws-lc-rs"] aws-lc = ["rustls", "rustls/aws-lc-rs", "tokio-rustls/aws-lc-rs"]
ring = ["rustls/ring", "tokio-rustls/ring"] ring = ["rustls", "rustls/ring", "tokio-rustls/ring"]
rustls = ["dep:rustls", "dep:tokio-rustls"]
openssl = ["dep:openssl", "dep:tokio-openssl"]
afc = ["dep:chrono"] afc = ["dep:chrono"]
amfi = [] amfi = []

View File

@@ -1,11 +1,12 @@
#![doc = include_str!("../README.md")] #![doc = include_str!("../README.md")]
// Jackson Coxson // Jackson Coxson
#[cfg(feature = "pair")] #[cfg(all(feature = "pair", feature = "rustls"))]
mod ca; mod ca;
pub mod pairing_file; pub mod pairing_file;
pub mod plist_macro; pub mod plist_macro;
pub mod provider; pub mod provider;
#[cfg(feature = "rustls")]
mod sni; mod sni;
#[cfg(feature = "tunnel_tcp_stack")] #[cfg(feature = "tunnel_tcp_stack")]
pub mod tcp; pub mod tcp;
@@ -27,6 +28,7 @@ pub use services::*;
pub use xpc::RemoteXpcClient; pub use xpc::RemoteXpcClient;
use provider::{IdeviceProvider, RsdProvider}; use provider::{IdeviceProvider, RsdProvider};
#[cfg(feature = "rustls")]
use rustls::{crypto::CryptoProvider, pki_types::ServerName}; use rustls::{crypto::CryptoProvider, pki_types::ServerName};
use std::{ use std::{
io::{self, BufWriter}, io::{self, BufWriter},
@@ -460,6 +462,8 @@ impl Idevice {
&mut self, &mut self,
pairing_file: &pairing_file::PairingFile, pairing_file: &pairing_file::PairingFile,
) -> Result<(), IdeviceError> { ) -> Result<(), IdeviceError> {
#[cfg(feature = "rustls")]
{
if CryptoProvider::get_default().is_none() { if CryptoProvider::get_default().is_none() {
// rust-analyzer will choke on this block, don't worry about it // rust-analyzer will choke on this block, don't worry about it
let crypto_provider: CryptoProvider = { let crypto_provider: CryptoProvider = {
@@ -488,7 +492,9 @@ impl Idevice {
// My sanity while debugging the workspace crates are more important. // My sanity while debugging the workspace crates are more important.
debug!("Using ring crypto backend, because both were passed"); debug!("Using ring crypto backend, because both were passed");
tracing::warn!("Both ring && aws-lc are selected as idevice crypto backends!"); tracing::warn!(
"Both ring && aws-lc are selected as idevice crypto backends!"
);
rustls::crypto::ring::default_provider() rustls::crypto::ring::default_provider()
} }
}; };
@@ -512,6 +518,29 @@ impl Idevice {
Ok(()) Ok(())
} }
#[cfg(all(feature = "openssl", not(feature = "rustls")))]
{
let connector =
openssl::ssl::SslConnector::builder(openssl::ssl::SslMethod::tls()).unwrap();
let mut connector = connector
.build()
.configure()
.unwrap()
.into_ssl("ur mom")
.unwrap();
connector.set_certificate(&pairing_file.host_certificate)?;
connector.set_private_key(&pairing_file.host_private_key)?;
connector.set_verify(openssl::ssl::SslVerifyMode::empty());
let socket = self.socket.take().unwrap();
let mut ssl_stream = tokio_openssl::SslStream::new(connector, socket)?;
std::pin::Pin::new(&mut ssl_stream).connect().await?;
self.socket = Some(Box::new(ssl_stream));
Ok(())
}
}
} }
/// Comprehensive error type for all device communication failures /// Comprehensive error type for all device communication failures
@@ -521,12 +550,24 @@ impl Idevice {
pub enum IdeviceError { pub enum IdeviceError {
#[error("device socket io failed")] #[error("device socket io failed")]
Socket(#[from] io::Error) = -1, Socket(#[from] io::Error) = -1,
#[cfg(all(feature = "rustls", not(feature = "openssl")))]
#[error("PEM parse failed")] #[error("PEM parse failed")]
PemParseFailed(#[from] rustls::pki_types::pem::Error) = -2, PemParseFailed(#[from] rustls::pki_types::pem::Error) = -2,
#[cfg(all(feature = "rustls", not(feature = "openssl")))]
#[error("TLS error")] #[error("TLS error")]
Rustls(#[from] rustls::Error) = -3, Rustls(#[from] rustls::Error) = -3,
#[cfg(all(feature = "openssl", not(feature = "rustls")))]
#[error("TLS error")]
Rustls(#[from] openssl::ssl::Error) = -3,
#[cfg(all(feature = "rustls", not(feature = "openssl")))]
#[error("TLS verifiction build failed")] #[error("TLS verifiction build failed")]
TlsBuilderFailed(#[from] rustls::server::VerifierBuilderError) = -4, TlsBuilderFailed(#[from] rustls::server::VerifierBuilderError) = -4,
#[cfg(all(feature = "openssl", not(feature = "rustls")))]
#[error("TLS verifiction build failed")]
TlsBuilderFailed(#[from] openssl::error::ErrorStack) = -4,
#[error("io on plist")] #[error("io on plist")]
Plist(#[from] plist::Error) = -5, Plist(#[from] plist::Error) = -5,
#[error("can't convert bytes to utf8")] #[error("can't convert bytes to utf8")]

View File

@@ -5,7 +5,13 @@
use std::path::Path; use std::path::Path;
#[cfg(feature = "openssl")]
use openssl::{
pkey::{PKey, Private},
x509::X509,
};
use plist::Data; use plist::Data;
#[cfg(feature = "rustls")]
use rustls::pki_types::{CertificateDer, pem::PemObject}; use rustls::pki_types::{CertificateDer, pem::PemObject};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tracing::warn; use tracing::warn;
@@ -14,6 +20,7 @@ use tracing::warn;
/// ///
/// Contains all cryptographic materials and identifiers needed for secure communication /// Contains all cryptographic materials and identifiers needed for secure communication
/// with an iOS device, including certificates, private keys, and device identifiers. /// with an iOS device, including certificates, private keys, and device identifiers.
#[cfg(feature = "rustls")]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct PairingFile { pub struct PairingFile {
/// Device's certificate in DER format /// Device's certificate in DER format
@@ -38,6 +45,21 @@ pub struct PairingFile {
pub udid: Option<String>, pub udid: Option<String>,
} }
#[cfg(all(feature = "openssl", not(feature = "rustls")))]
#[derive(Clone, Debug)]
pub struct PairingFile {
pub device_certificate: X509,
pub host_private_key: PKey<Private>,
pub host_certificate: X509,
pub root_private_key: PKey<Private>,
pub root_certificate: X509,
pub system_buid: String,
pub host_id: String,
pub escrow_bag: Vec<u8>,
pub wifi_mac_address: String,
pub udid: Option<String>,
}
/// Internal representation of a pairing file for serialization/deserialization /// Internal representation of a pairing file for serialization/deserialization
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "PascalCase")] #[serde(rename_all = "PascalCase")]
@@ -133,6 +155,7 @@ impl PairingFile {
/// ///
/// # Errors /// # Errors
/// Returns `IdeviceError` if serialization fails /// Returns `IdeviceError` if serialization fails
#[cfg(feature = "rustls")]
pub fn serialize(self) -> Result<Vec<u8>, crate::IdeviceError> { pub fn serialize(self) -> Result<Vec<u8>, crate::IdeviceError> {
let raw = RawPairingFile::from(self); let raw = RawPairingFile::from(self);
@@ -140,8 +163,18 @@ impl PairingFile {
plist::to_writer_xml(&mut buf, &raw)?; plist::to_writer_xml(&mut buf, &raw)?;
Ok(buf) Ok(buf)
} }
#[cfg(all(feature = "openssl", not(feature = "rustls")))]
pub fn serialize(self) -> Result<Vec<u8>, crate::IdeviceError> {
let raw = RawPairingFile::try_from(self)?;
let mut buf = Vec::new();
plist::to_writer_xml(&mut buf, &raw)?;
Ok(buf)
}
} }
#[cfg(feature = "rustls")]
impl TryFrom<RawPairingFile> for PairingFile { impl TryFrom<RawPairingFile> for PairingFile {
type Error = rustls::pki_types::pem::Error; type Error = rustls::pki_types::pem::Error;
@@ -180,6 +213,30 @@ impl TryFrom<RawPairingFile> for PairingFile {
} }
} }
#[cfg(all(feature = "openssl", not(feature = "rustls")))]
impl TryFrom<RawPairingFile> for PairingFile {
type Error = openssl::error::ErrorStack;
fn try_from(value: RawPairingFile) -> Result<Self, Self::Error> {
Ok(Self {
device_certificate: X509::from_pem(&Into::<Vec<u8>>::into(value.device_certificate))?,
host_private_key: PKey::private_key_from_pem(&Into::<Vec<u8>>::into(
value.host_private_key,
))?,
host_certificate: X509::from_pem(&Into::<Vec<u8>>::into(value.host_certificate))?,
root_private_key: PKey::private_key_from_pem(&Into::<Vec<u8>>::into(
value.root_private_key,
))?,
root_certificate: X509::from_pem(&Into::<Vec<u8>>::into(value.root_certificate))?,
system_buid: value.system_buid,
host_id: value.host_id,
escrow_bag: value.escrow_bag.into(),
wifi_mac_address: value.wifi_mac_address,
udid: value.udid,
})
}
}
impl From<PairingFile> for RawPairingFile { impl From<PairingFile> for RawPairingFile {
/// Converts a structured pairing file into a raw pairing file for serialization /// Converts a structured pairing file into a raw pairing file for serialization
fn from(value: PairingFile) -> Self { fn from(value: PairingFile) -> Self {

View File

@@ -243,7 +243,7 @@ impl LockdownClient {
/// ///
/// # Errors /// # Errors
/// Returns `IdeviceError` /// Returns `IdeviceError`
#[cfg(feature = "pair")] #[cfg(all(feature = "pair", feature = "rustls"))]
pub async fn pair( pub async fn pair(
&mut self, &mut self,
host_id: impl Into<String>, host_id: impl Into<String>,

View File

@@ -161,3 +161,4 @@ futures-util = { version = "0.3" }
default = ["aws-lc"] default = ["aws-lc"]
aws-lc = ["idevice/aws-lc"] aws-lc = ["idevice/aws-lc"]
ring = ["idevice/ring"] ring = ["idevice/ring"]
openssl = ["idevice/openssl"]