Skip to content

Commit 2ffe630

Browse files
committed
Circle client
1 parent 3b160a7 commit 2ffe630

File tree

2 files changed

+21
-10
lines changed

2 files changed

+21
-10
lines changed

icloud-auth/rustcrypto-srp/src/client.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ impl<'a, D: Digest> SrpClient<'a, D> {
184184
password: &[u8],
185185
salt: &[u8],
186186
b_pub: &[u8],
187+
is_gsa_empty_hash: bool,
187188
) -> Result<SrpClientVerifier<D>, SrpAuthError> {
188189
let a = BigUint::from_bytes_be(a);
189190
// let a_pub = BigUint::from_bytes_be(&a_pub_bytes);
@@ -198,7 +199,7 @@ impl<'a, D: Digest> SrpClient<'a, D> {
198199

199200
let u = compute_u::<D>(&a_pub.to_bytes_be(), &b_pub.to_bytes_be());
200201
let k = compute_k::<D>(self.params);
201-
let identity_hash = Self::compute_identity_hash(&[], password);
202+
let identity_hash = Self::compute_identity_hash(if is_gsa_empty_hash { &[] } else { username }, password);
202203
let x = Self::compute_x(identity_hash.as_slice(), salt);
203204

204205
let key = self.compute_premaster_secret(&b_pub, &k, &x, &a, &u);

icloud-auth/src/client.rs

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ pub struct AppleAccount<T: AnisetteProvider> {
110110
pub struct CircleSendMessage {
111111
pub atxid: String,
112112
pub circlestep: u32,
113-
pub idmsdata: String,
113+
pub idmsdata: Option<String>,
114114
pub pakedata: String,
115115
pub ptkn: String,
116116
pub ec: Option<i32>,
@@ -350,7 +350,8 @@ impl<T: AnisetteProvider> AppleAccount<T> {
350350

351351
pub async fn circle(
352352
&mut self,
353-
message: &CircleSendMessage
353+
message: &CircleSendMessage,
354+
is_twofa: bool,
354355
) -> Result<LoginState, Error> {
355356

356357
let valid_anisette = self.get_anisette().await?;
@@ -361,12 +362,21 @@ impl<T: AnisetteProvider> AppleAccount<T> {
361362
HeaderValue::from_str("text/x-xml-plist").unwrap(),
362363
);
363364

364-
let token = self.get_token("com.apple.gs.idms.hb").await.ok_or(Error::HappyBirthdayError)?;
365-
366365
gsa_headers.insert("Accept", HeaderValue::from_str("*/*").unwrap());
367366
gsa_headers.extend(valid_anisette.get_circle_headers().into_iter().map(|(a, b)| (HeaderName::from_str(&a).unwrap(), HeaderValue::from_str(&b).unwrap())));
368-
gsa_headers.insert("X-Apple-HB-Token", HeaderValue::from_str(&base64::encode(format!("{}:{}", self.spd.as_ref().unwrap().get("adsid").expect("no adsid!!").as_string().unwrap(), token))).unwrap());
369-
367+
368+
if is_twofa {
369+
let spd = self.spd.as_ref().unwrap();
370+
let dsid = spd.get("adsid").unwrap().as_string().unwrap();
371+
let token = spd.get("GsIdmsToken").unwrap().as_string().unwrap();
372+
373+
let identity_token = base64::encode(format!("{}:{}", dsid, token));
374+
gsa_headers.insert("X-Apple-Identity-Token", HeaderValue::from_str(&identity_token).unwrap());
375+
} else {
376+
let token = self.get_token("com.apple.gs.idms.hb").await.ok_or(Error::HappyBirthdayError)?;
377+
gsa_headers.insert("X-Apple-HB-Token", HeaderValue::from_str(&base64::encode(format!("{}:{}", self.spd.as_ref().unwrap().get("adsid").expect("no adsid!!").as_string().unwrap(), token))).unwrap());
378+
}
379+
370380
let data = plist::to_value(&message)?;
371381

372382
let packet = Dictionary::from_iter([
@@ -456,7 +466,7 @@ impl<T: AnisetteProvider> AppleAccount<T> {
456466
let mut data = Dictionary::from_iter([
457467
("cdpStatus", Value::Boolean(true)),
458468
("cfuids", Value::Array(vec![])),
459-
("circleStatus", Value::Boolean(false)),
469+
("circleStatus", Value::Boolean(true)),
460470
("denyICloudWebAccess", Value::Boolean(true)),
461471
("dn", Value::String(device_name.to_string())),
462472
("event", Value::String("liveness".to_string())),
@@ -632,7 +642,7 @@ impl<T: AnisetteProvider> AppleAccount<T> {
632642
}
633643
// println!("{:?}", res);
634644
let salt = res.get("s").unwrap().as_data().unwrap();
635-
let b_pub = res.get("B").unwrap().as_data().unwrap();
645+
let b_pub = res.get("B").unwrap().as_data().unwrap(); // got this
636646
let iters = res.get("i").unwrap().as_signed_integer().unwrap();
637647
let c = res.get("c").unwrap().as_string().unwrap();
638648

@@ -646,7 +656,7 @@ impl<T: AnisetteProvider> AppleAccount<T> {
646656
);
647657

648658
let verifier: SrpClientVerifier<Sha256> = srp_client
649-
.process_reply(&a, &username.as_bytes(), &password_buf, salt, b_pub)
659+
.process_reply(&a, &username.as_bytes(), &password_buf, salt, b_pub, true)
650660
.unwrap();
651661

652662
let m = verifier.proof();

0 commit comments

Comments
 (0)