Add examples and first attempt at getting push tokens.
Dadoum

Dadoum commited on 2026-09-28 17:31:15
Showing 14 changed files, with 2125 additions and 1 deletions.

... ...
@@ -321,6 +321,23 @@ dependencies = [
321 321
  "x509-cert",
322 322
 ]
323 323
 
324
+[[package]]
325
+name = "aps"
326
+version = "0.1.0"
327
+dependencies = [
328
+ "bytes",
329
+ "plist",
330
+ "reqwest",
331
+ "rsa",
332
+ "serde",
333
+ "sha1 0.11.0",
334
+ "thiserror 2.0.18",
335
+ "tokio",
336
+ "tokio-rustls",
337
+ "uuid",
338
+ "x509-cert",
339
+]
340
+
324 341
 [[package]]
325 342
 name = "ar_archive_writer"
326 343
 version = "0.5.2"
... ...
@@ -7577,7 +7594,9 @@ dependencies = [
7577 7594
  "bytes",
7578 7595
  "libc",
7579 7596
  "mio",
7597
+ "parking_lot",
7580 7598
  "pin-project-lite",
7599
+ "signal-hook-registry",
7581 7600
  "socket2",
7582 7601
  "tokio-macros",
7583 7602
  "windows-sys 0.61.2",
... ...
@@ -9250,6 +9269,8 @@ name = "xcode"
9250 9269
 version = "0.1.0"
9251 9270
 dependencies = [
9252 9271
  "adi",
9272
+ "android-coreadi",
9273
+ "env_logger",
9253 9274
  "grandslam",
9254 9275
  "plist",
9255 9276
  "plist-macros",
... ...
@@ -9258,6 +9279,7 @@ dependencies = [
9258 9279
  "serde_bytes",
9259 9280
  "sys-locale",
9260 9281
  "thiserror 2.0.18",
9282
+ "tokio",
9261 9283
  "uuid",
9262 9284
 ]
9263 9285
 
... ...
@@ -1,11 +1,12 @@
1 1
 [workspace]
2 2
 resolver = "2"
3
-members = ["adi", "adid-proxy", "android-coreadi", "grandslam", "apple-codesign-quick", "elf-loader", "fairplay", "itunes", "library-coreadi", "plist-macros", "purple-builder", "super-sideloader", "xcode"]
3
+members = ["adi", "adid-proxy", "android-coreadi", "aps", "grandslam", "apple-codesign-quick", "elf-loader", "fairplay", "itunes", "library-coreadi", "plist-macros", "purple-builder", "super-sideloader", "xcode"]
4 4
 
5 5
 [workspace.dependencies]
6 6
 adi = { path = "adi" }
7 7
 adid-proxy = { path = "adid-proxy" }
8 8
 android-coreadi = { path = "android-coreadi" }
9
+aps = { path = "aps" }
9 10
 elf-loader = { path = "elf-loader" }
10 11
 grandslam = { path = "grandslam" }
11 12
 itunes = { path = "itunes" }
... ...
@@ -0,0 +1,20 @@
1
+[package]
2
+name = "aps"
3
+version = "0.1.0"
4
+edition = "2024"
5
+description = "Apple Push Service device activation and courier connections"
6
+repository = "https://github.com/Dadoum/apple-crates"
7
+license = "LGPL-2.1-or-later"
8
+
9
+[dependencies]
10
+bytes = "1"
11
+plist.workspace = true
12
+reqwest = { workspace = true, features = ["form"] }
13
+sha1.workspace = true
14
+thiserror.workspace = true
15
+tokio = { workspace = true, features = ["net", "io-util", "time"] }
16
+tokio-rustls = { version = "0.26", default-features = false, features = ["ring", "tls12"] }
17
+rsa = "0.9.10"
18
+serde = { version = "1", features = ["derive"] }
19
+uuid = { version = "1", features = ["v4"] }
20
+x509-cert = "0.2.5"
... ...
@@ -0,0 +1,93 @@
1
+# aps
2
+
3
+Apple Push Service activation and courier connections. Activation is an HTTP
4
+request that returns a device certificate. The subsequent APS handshake over
5
+TLS returns a push token. Neither step needs an Apple account or anisette.
6
+
7
+```rust,ignore
8
+let identity = aps::activate(&client, &device, &signer).await?;
9
+let mut connection = aps::PushConnection::connect(&client, identity).await?;
10
+
11
+// AuthKit's check-in represents the token as lowercase hexadecimal.
12
+let device_data = grandslam::DeviceData {
13
+    push_token: Some(connection.push_token().to_string()),
14
+    ..Default::default()
15
+};
16
+
17
+connection.set_topics(&["com.apple.idmsauth"]).await?;
18
+loop {
19
+    let notification = connection.receive().await?;
20
+    // Interpret notification.payload according to its topic.
21
+}
22
+```
23
+
24
+`ActivationDevice` contains the actual device fields sent in the activation
25
+plist. `ActivationSigner::sign` receives the exact serialized XML and returns
26
+its FairPlay signature and matching certificate chain. The signer holds the
27
+activation signing identity; the library generates a separate RSA device key
28
+and CSR. A returned `PushIdentity` always contains the matching device key and
29
+certificate, and a returned `PushConnection` always has a token.
30
+
31
+Errors follow those boundaries: `IdentityError`, `ActivationError<S::Error>`,
32
+`ConnectError`, and `CourierError`. Signer errors keep their concrete type.
33
+Connecting moves the identity into the connection; reconnecting reuses it
34
+without cloning the private key.
35
+
36
+The signer is synchronous, like a local cryptographic provider. Applications
37
+using a slow signer should schedule activation accordingly. The built-in Windows
38
+signer uses embedded constants and Rust cryptography.
39
+
40
+## Connection lifetime and persistence
41
+
42
+`receive` handles notification acknowledgements and ping/pong traffic. Keep it
43
+running while expecting pushes. There are no hidden background tasks or retry
44
+loops. Call `reconnect` after transport failure; it reuses the identity/token
45
+and restores the enabled topics. Use `close` to shut down deliberately. A
46
+token's existence does not mean a connection is currently reachable.
47
+If cancelling `receive` during an acknowledgement or keepalive write, reconnect
48
+before continuing.
49
+
50
+Persist the device certificate, private key, and latest token together.
51
+`PushIdentity::certificate` returns DER bytes; `private_key` exposes the RSA key
52
+for PKCS#8 export or a future adapter. `PushIdentity::new` validates imported
53
+certificate/key pairs. `PushToken` supports serde and exposes `as_bytes`, but
54
+has no public field or arbitrary-byte constructor. Its Debug output is redacted.
55
+`PushConnection::resume` accepts the restored identity and token; read
56
+`push_token` again afterward in case the server replaced it.
57
+
58
+The current transport implements the original APS TLV protocol and advertises
59
+`apns-security-v3`. It uses Apple's HTTPS configuration bag and verifies the
60
+courier's TLS certificate and hostname against the bundled
61
+[Apple Root CA](https://www.apple.com/appleca/AppleIncRootCertificate.cer). Notification
62
+payloads stay as bytes, allowing AuthKit and future iMessage consumers to decode
63
+them independently. IDS registration and iMessage-specific operations are not
64
+part of this crate.
65
+
66
+## Standalone Windows signing identity
67
+
68
+`WindowsActivationSigner::new()` selects one of ten embedded activation signing
69
+identities recovered from iCloud 15.10.39.0 x64. Their RSA primes and matching
70
+certificates live in a private constants module, with the shared CA chain stored
71
+once. No DLL or extraction step is needed. Signing errors use `rsa::Error`.
72
+
73
+```sh
74
+cargo run -p aps --example push_token -- /path/to/push-state.plist
75
+```
76
+
77
+The example activates on its first run, subscribes to `com.apple.idmsauth`,
78
+saves the identity/token, and closes the connection. Subsequent runs restore
79
+that state. The state file contains a private key; the example requests mode
80
+0600 when creating it on Unix. Applications should use their own credential
81
+storage. Restoring saved state does not perform activation again.
82
+
83
+Activation was traced in `APSDaemon_main.dll` at `0x18001e770`; its signing
84
+wrapper is at `0x180005250`. The APS protocol was cross-checked against Apple's
85
+Windows client and rustpush's public protocol implementation. This crate does
86
+not depend on rustpush or its account APIs.
87
+
88
+See [the signing format notes](docs/windows-signing.md) for the decoded wrapping
89
+format and its provenance.
90
+
91
+All ten embedded identities passed independent RSA signature verification.
92
+The standalone Rust signer also completed live activation and obtained a
93
+32-byte push token; restoring that state reused the same token without a DLL.
... ...
@@ -0,0 +1,113 @@
1
+//! cargo run -p aps --example push_token -- STATE.plist
2
+use aps::{ActivationDevice, PushConnection, PushIdentity, PushToken, WindowsActivationSigner};
3
+use plist::Data;
4
+use rsa::{
5
+    RsaPrivateKey,
6
+    pkcs8::{DecodePrivateKey, EncodePrivateKey},
7
+};
8
+use serde::{Deserialize, Serialize};
9
+use std::{fs, io, path::PathBuf, time::Duration};
10
+use thiserror::Error;
11
+
12
+#[derive(Debug, Error)]
13
+enum ExampleError {
14
+    #[error("usage: push_token STATE.plist")]
15
+    Usage,
16
+    #[error(transparent)]
17
+    Io(#[from] io::Error),
18
+    #[error(transparent)]
19
+    Http(#[from] reqwest::Error),
20
+    #[error(transparent)]
21
+    Plist(#[from] plist::Error),
22
+    #[error(transparent)]
23
+    Key(#[from] rsa::pkcs8::Error),
24
+    #[error(transparent)]
25
+    Identity(#[from] aps::IdentityError),
26
+    #[error(transparent)]
27
+    Activation(#[from] aps::ActivationError<rsa::Error>),
28
+    #[error(transparent)]
29
+    Connect(#[from] aps::ConnectError),
30
+    #[error(transparent)]
31
+    Courier(#[from] aps::CourierError),
32
+}
33
+
34
+#[derive(Serialize, Deserialize)]
35
+struct SavedState {
36
+    certificate: Data,
37
+    private_key: Data,
38
+    token: PushToken,
39
+}
40
+
41
+#[tokio::main]
42
+async fn main() -> Result<(), ExampleError> {
43
+    let args: Vec<_> = std::env::args_os().skip(1).collect();
44
+    if args.len() != 1 {
45
+        return Err(ExampleError::Usage);
46
+    }
47
+    let state_path = PathBuf::from(&args[0]);
48
+    let client = reqwest::Client::builder()
49
+        .timeout(Duration::from_secs(30))
50
+        .build()?;
51
+    let mut connection = match fs::read(&state_path) {
52
+        Ok(bytes) => {
53
+            let state: SavedState = plist::from_bytes(&bytes)?;
54
+            let identity = PushIdentity::new(
55
+                state.certificate.into(),
56
+                RsaPrivateKey::from_pkcs8_der(state.private_key.as_ref())?,
57
+            )?;
58
+            let connection = PushConnection::resume(&client, identity, &state.token).await?;
59
+            println!(
60
+                "Resumed APS; token unchanged: {}",
61
+                connection.push_token() == &state.token
62
+            );
63
+            connection
64
+        }
65
+        Err(error) if error.kind() == io::ErrorKind::NotFound => {
66
+            let udid = uuid::Uuid::new_v4().to_string().to_uppercase();
67
+            // Values observed in Apple's Windows activation client.
68
+            let device = ActivationDevice {
69
+                device_class: "Windows",
70
+                product_type: "windows1,1",
71
+                product_version: "10.6.4",
72
+                build_version: "10.6.4",
73
+                serial_number: "WindowSerial",
74
+                unique_device_id: &udid,
75
+            };
76
+            let signer = WindowsActivationSigner::new();
77
+            let identity = aps::activate(&client, &device, &signer).await?;
78
+            println!(
79
+                "Activated; device certificate is {} bytes",
80
+                identity.certificate().len()
81
+            );
82
+            PushConnection::connect(&client, identity).await?
83
+        }
84
+        Err(error) => return Err(error.into()),
85
+    };
86
+    connection.set_topics(&["com.apple.idmsauth"]).await?;
87
+    let state = SavedState {
88
+        certificate: connection.identity().certificate().to_vec().into(),
89
+        private_key: connection
90
+            .identity()
91
+            .private_key()
92
+            .to_pkcs8_der()?
93
+            .as_bytes()
94
+            .to_vec()
95
+            .into(),
96
+        token: connection.push_token().clone(),
97
+    };
98
+    let mut options = fs::OpenOptions::new();
99
+    options.write(true).create(true).truncate(true);
100
+    #[cfg(unix)]
101
+    {
102
+        use std::os::unix::fs::OpenOptionsExt;
103
+        options.mode(0o600);
104
+    }
105
+    plist::to_writer_xml(options.open(&state_path)?, &state)?;
106
+    println!(
107
+        "Connected; saved identity and {}-byte token to {}",
108
+        connection.push_token().as_bytes().len(),
109
+        state_path.display()
110
+    );
111
+    connection.close().await?;
112
+    Ok(())
113
+}
... ...
@@ -0,0 +1,210 @@
1
+use plist::{Dictionary, Value};
2
+use reqwest::Client;
3
+use rsa::{
4
+    Pkcs1v15Sign, RsaPrivateKey, RsaPublicKey,
5
+    pkcs8::{DecodePublicKey, EncodePublicKey},
6
+    rand_core::OsRng,
7
+};
8
+use sha1::{Digest, Sha1};
9
+use thiserror::Error;
10
+use uuid::Uuid;
11
+use x509_cert::{
12
+    Certificate,
13
+    der::{
14
+        Decode, DecodePem, Encode, EncodePem,
15
+        asn1::{Any, BitString},
16
+        pem::LineEnding,
17
+    },
18
+    request::{CertReq, CertReqInfo},
19
+    spki::{AlgorithmIdentifierOwned, ObjectIdentifier, SubjectPublicKeyInfoOwned},
20
+};
21
+
22
+#[derive(Debug, Error)]
23
+pub enum IdentityError {
24
+    #[error("Invalid RSA private key: {0}")]
25
+    PrivateKey(#[from] rsa::Error),
26
+    #[error("Invalid device certificate: {0}")]
27
+    Certificate(#[from] x509_cert::der::Error),
28
+    #[error("Invalid certificate public key: {0}")]
29
+    PublicKey(#[from] rsa::pkcs8::spki::Error),
30
+    #[error("The certificate does not match the private key")]
31
+    KeyMismatch,
32
+}
33
+
34
+#[derive(Debug, Error)]
35
+pub enum ActivationError<E> {
36
+    #[error("Activation request failed: {0}")]
37
+    Request(#[from] reqwest::Error),
38
+    #[error("Activation plist error: {0}")]
39
+    Plist(#[from] plist::Error),
40
+    #[error("RSA key generation or CSR signing failed: {0}")]
41
+    Rsa(#[from] rsa::Error),
42
+    #[error("Certificate/CSR encoding error: {0}")]
43
+    Der(#[from] x509_cert::der::Error),
44
+    #[error("Public key encoding error: {0}")]
45
+    PublicKey(#[from] rsa::pkcs8::spki::Error),
46
+    #[error("Activation signing failed: {0}")]
47
+    Signing(#[source] E),
48
+    #[error("Invalid activation response")]
49
+    InvalidResponse(Vec<u8>),
50
+    #[error("Invalid activated identity: {0}")]
51
+    Identity(#[from] IdentityError),
52
+}
53
+
54
+/// Fields placed in Apple's activation-info plist, excluding the generated CSR
55
+/// and activation nonce. `device_class` also selects the activation endpoint.
56
+pub struct ActivationDevice<'a> {
57
+    pub device_class: &'a str,
58
+    pub product_type: &'a str,
59
+    pub product_version: &'a str,
60
+    pub build_version: &'a str,
61
+    pub serial_number: &'a str,
62
+    pub unique_device_id: &'a str,
63
+}
64
+
65
+/// The matching pair sent as FairPlaySignature and FairPlayCertChain.
66
+pub struct ActivationSignature {
67
+    pub signature: Vec<u8>,
68
+    /// Concatenated DER certificates, leaf first.
69
+    pub certificate_chain: Vec<u8>,
70
+}
71
+
72
+/// Signs the exact serialized ActivationInfoXML bytes using an activation
73
+/// signing identity. This is separate from the newly generated device key.
74
+pub trait ActivationSigner {
75
+    type Error: std::error::Error + 'static;
76
+
77
+    fn sign(&self, activation_info_xml: &[u8]) -> Result<ActivationSignature, Self::Error>;
78
+}
79
+
80
+/// The device certificate issued by Apple and its matching private key.
81
+/// Keep both when persisting an identity; a token alone cannot authenticate APS.
82
+#[derive(Clone)]
83
+pub struct PushIdentity {
84
+    certificate: Vec<u8>,
85
+    private_key: RsaPrivateKey,
86
+}
87
+
88
+impl PushIdentity {
89
+    /// Imports a DER device certificate and checks that it matches the key.
90
+    pub fn new(certificate: Vec<u8>, private_key: RsaPrivateKey) -> Result<Self, IdentityError> {
91
+        private_key.validate()?;
92
+        let parsed = Certificate::from_der(&certificate)?;
93
+        let public = RsaPublicKey::from_public_key_der(
94
+            &parsed.tbs_certificate.subject_public_key_info.to_der()?,
95
+        )?;
96
+        if public != private_key.to_public_key() {
97
+            return Err(IdentityError::KeyMismatch);
98
+        }
99
+        Ok(Self {
100
+            certificate,
101
+            private_key,
102
+        })
103
+    }
104
+
105
+    pub fn certificate(&self) -> &[u8] {
106
+        &self.certificate
107
+    }
108
+
109
+    pub fn private_key(&self) -> &RsaPrivateKey {
110
+        &self.private_key
111
+    }
112
+}
113
+
114
+pub(crate) fn sign_sha1(key: &RsaPrivateKey, data: &[u8]) -> Result<Vec<u8>, rsa::Error> {
115
+    // SHA-1 DigestInfo (OID 1.3.14.3.2.26), followed by the 20-byte hash.
116
+    let mut digest_info = [0; 35];
117
+    digest_info[..15].copy_from_slice(&[
118
+        0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14,
119
+    ]);
120
+    digest_info[15..].copy_from_slice(&Sha1::digest(data));
121
+    key.sign_with_rng(&mut OsRng, Pkcs1v15Sign::new_unprefixed(), &digest_info)
122
+}
123
+
124
+/// Generates a device key and CSR, then requests an activation certificate.
125
+/// Use a plain HTTP client; account authentication headers are not needed here.
126
+pub async fn activate<S: ActivationSigner>(
127
+    client: &Client,
128
+    device: &ActivationDevice<'_>,
129
+    signer: &S,
130
+) -> Result<PushIdentity, ActivationError<S::Error>> {
131
+    let private_key = RsaPrivateKey::new(&mut OsRng, 1024)?;
132
+    let info = CertReqInfo {
133
+        version: Default::default(),
134
+        subject: "CN=Client Push Certificate".parse()?,
135
+        public_key: SubjectPublicKeyInfoOwned::from_der(
136
+            private_key.to_public_key().to_public_key_der()?.as_bytes(),
137
+        )?,
138
+        attributes: Default::default(),
139
+    };
140
+    let signature = sign_sha1(&private_key, &info.to_der()?)?;
141
+    let csr = CertReq {
142
+        info,
143
+        algorithm: AlgorithmIdentifierOwned {
144
+            oid: ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.5"),
145
+            parameters: Some(Any::null()),
146
+        },
147
+        signature: BitString::from_bytes(&signature)?,
148
+    }
149
+    .to_pem(LineEnding::LF)?;
150
+
151
+    let mut info = Dictionary::new();
152
+    for (name, value) in [
153
+        ("DeviceClass", device.device_class),
154
+        ("ProductType", device.product_type),
155
+        ("ProductVersion", device.product_version),
156
+        ("BuildVersion", device.build_version),
157
+        ("SerialNumber", device.serial_number),
158
+        ("UniqueDeviceID", device.unique_device_id),
159
+        ("ActivationState", "Unactivated"),
160
+    ] {
161
+        info.insert(name.into(), value.into());
162
+    }
163
+    info.insert(
164
+        "ActivationRandomness".into(),
165
+        Uuid::new_v4().to_string().to_uppercase().into(),
166
+    );
167
+    info.insert("DeviceCertRequest".into(), Value::Data(csr.into_bytes()));
168
+    let mut xml = Vec::new();
169
+    plist::to_writer_xml(&mut xml, &info)?;
170
+    let signed = signer.sign(&xml).map_err(ActivationError::Signing)?;
171
+    let envelope = Dictionary::from_iter([
172
+        ("ActivationInfoComplete", Value::Boolean(true)),
173
+        ("ActivationInfoXML", Value::Data(xml)),
174
+        ("FairPlaySignature", Value::Data(signed.signature)),
175
+        ("FairPlayCertChain", Value::Data(signed.certificate_chain)),
176
+    ]);
177
+    let mut body = Vec::new();
178
+    plist::to_writer_xml(&mut body, &envelope)?;
179
+    let response = client
180
+        .post("https://albert.apple.com/WebObjects/ALUnbrick.woa/wa/deviceActivation")
181
+        .query(&[("device", device.device_class)])
182
+        .form(&[("activation-info", String::from_utf8_lossy(&body).as_ref())])
183
+        .send()
184
+        .await?
185
+        .error_for_status()?
186
+        .bytes()
187
+        .await?;
188
+    // The Windows endpoint wraps the response plist in an HTML Protocol element.
189
+    let text = String::from_utf8_lossy(&response);
190
+    let payload = match text.split_once("<Protocol>") {
191
+        Some((_, rest)) => rest
192
+            .split_once("</Protocol>")
193
+            .map(|(plist, _)| plist)
194
+            .ok_or_else(|| ActivationError::InvalidResponse(response.to_vec()))?,
195
+        None => &text,
196
+    };
197
+    let parsed: Value = plist::from_bytes(payload.as_bytes())
198
+        .map_err(|_| ActivationError::InvalidResponse(response.to_vec()))?;
199
+    let certificate = parsed
200
+        .as_dictionary()
201
+        .and_then(|d| d.get("device-activation"))
202
+        .and_then(Value::as_dictionary)
203
+        .and_then(|d| d.get("activation-record"))
204
+        .and_then(Value::as_dictionary)
205
+        .and_then(|d| d.get("DeviceCertificate"))
206
+        .and_then(Value::as_data)
207
+        .ok_or_else(|| ActivationError::InvalidResponse(response.to_vec()))?;
208
+    let certificate = Certificate::from_pem(certificate)?.to_der()?;
209
+    Ok(PushIdentity::new(certificate, private_key)?)
210
+}
... ...
@@ -0,0 +1,335 @@
1
+use crate::{
2
+    PushIdentity,
3
+    activation::sign_sha1,
4
+    protocol::{Command, CourierError, FrameReader, Message, TIMEOUT},
5
+};
6
+use bytes::Bytes;
7
+use plist::{Dictionary, Value};
8
+use reqwest::Client;
9
+use rsa::rand_core::{OsRng, RngCore};
10
+use serde::{Deserialize, Serialize};
11
+use sha1::{Digest, Sha1};
12
+use std::{
13
+    fmt, io,
14
+    sync::Arc,
15
+    time::{Duration, SystemTime, UNIX_EPOCH},
16
+};
17
+use thiserror::Error;
18
+use tokio::{
19
+    io::AsyncWriteExt,
20
+    net::TcpStream,
21
+    time::{Instant, sleep_until, timeout},
22
+};
23
+use tokio_rustls::{
24
+    TlsConnector,
25
+    client::TlsStream,
26
+    rustls::{
27
+        self, ClientConfig, RootCertStore,
28
+        crypto::ring,
29
+        pki_types::{CertificateDer, ServerName},
30
+    },
31
+};
32
+
33
+const KEEPALIVE: Duration = Duration::from_secs(60);
34
+
35
+#[derive(Debug, Error)]
36
+pub enum ConnectError {
37
+    #[error("APS configuration request failed: {0}")]
38
+    Request(#[from] reqwest::Error),
39
+    #[error("Invalid APS configuration plist: {0}")]
40
+    Plist(#[from] plist::Error),
41
+    #[error("Missing or invalid APS configuration field: {0}")]
42
+    Configuration(&'static str),
43
+    #[error("Invalid courier TLS hostname: {0}")]
44
+    Hostname(#[from] rustls::pki_types::InvalidDnsNameError),
45
+    #[error("TLS configuration failed: {0}")]
46
+    Tls(#[from] rustls::Error),
47
+    #[error("Courier connection failed: {0}")]
48
+    Io(#[from] io::Error),
49
+    #[error("Nonce signing failed: {0}")]
50
+    Signing(#[from] rsa::Error),
51
+    #[error("System clock precedes Unix epoch: {0}")]
52
+    Clock(#[from] std::time::SystemTimeError),
53
+    #[error("Courier handshake failed: {0}")]
54
+    Courier(#[from] CourierError),
55
+    #[error("APS rejected the connection with status {0}")]
56
+    Rejected(u8),
57
+    #[error("APS connection timed out")]
58
+    Timeout,
59
+}
60
+
61
+/// A courier-issued token. Display is the lowercase hex used by AuthKit.
62
+#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
63
+#[serde(transparent)]
64
+pub struct PushToken([u8; 32]);
65
+
66
+impl PushToken {
67
+    pub fn as_bytes(&self) -> &[u8; 32] {
68
+        &self.0
69
+    }
70
+}
71
+
72
+impl fmt::Display for PushToken {
73
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74
+        for byte in self.0 {
75
+            write!(f, "{byte:02x}")?;
76
+        }
77
+        Ok(())
78
+    }
79
+}
80
+
81
+impl fmt::Debug for PushToken {
82
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
83
+        f.write_str("PushToken([redacted])")
84
+    }
85
+}
86
+
87
+pub struct Notification {
88
+    pub id: u32,
89
+    /// SHA-1 of the topic name.
90
+    pub topic: [u8; 20],
91
+    /// Unmodified bytes sharing the received frame's allocation.
92
+    pub payload: Bytes,
93
+}
94
+
95
+/// A completed APS handshake and its live courier transport.
96
+/// Call `receive` to drive notifications and keepalive. No tasks are spawned.
97
+pub struct PushConnection {
98
+    identity: PushIdentity,
99
+    token: PushToken,
100
+    stream: TlsStream<TcpStream>,
101
+    reader: FrameReader,
102
+    topics: Vec<[u8; 20]>,
103
+    next_ping: Instant,
104
+    pong_deadline: Option<Instant>,
105
+}
106
+
107
+impl PushConnection {
108
+    /// Takes ownership of the identity without copying its private key.
109
+    pub async fn connect(client: &Client, identity: PushIdentity) -> Result<Self, ConnectError> {
110
+        Self::open(client, identity, None).await
111
+    }
112
+
113
+    /// Reuses a saved token and identity. Inspect `push_token` afterward in case
114
+    /// the server returned a replacement.
115
+    pub async fn resume(
116
+        client: &Client,
117
+        identity: PushIdentity,
118
+        token: &PushToken,
119
+    ) -> Result<Self, ConnectError> {
120
+        Self::open(client, identity, Some(token)).await
121
+    }
122
+
123
+    async fn open(
124
+        client: &Client,
125
+        identity: PushIdentity,
126
+        previous: Option<&PushToken>,
127
+    ) -> Result<Self, ConnectError> {
128
+        let (stream, reader, token) = timeout(TIMEOUT, handshake(client, &identity, previous))
129
+            .await
130
+            .map_err(|_| ConnectError::Timeout)??;
131
+        Ok(Self {
132
+            identity,
133
+            token,
134
+            stream,
135
+            reader,
136
+            topics: Vec::new(),
137
+            next_ping: Instant::now() + KEEPALIVE,
138
+            pong_deadline: None,
139
+        })
140
+    }
141
+
142
+    pub fn push_token(&self) -> &PushToken {
143
+        &self.token
144
+    }
145
+
146
+    pub fn identity(&self) -> &PushIdentity {
147
+        &self.identity
148
+    }
149
+
150
+    /// Reuses the current identity/token and restores topics. Failed attempts
151
+    /// leave the existing identity and token available for another attempt.
152
+    pub async fn reconnect(&mut self, client: &Client) -> Result<(), ConnectError> {
153
+        let (mut stream, reader, token) = timeout(
154
+            TIMEOUT,
155
+            handshake(client, &self.identity, Some(&self.token)),
156
+        )
157
+        .await
158
+        .map_err(|_| ConnectError::Timeout)??;
159
+        Message::Filter {
160
+            token: &token,
161
+            topics: &self.topics,
162
+        }
163
+        .write(&mut stream)
164
+        .await?;
165
+        self.stream = stream;
166
+        self.reader = reader;
167
+        self.token = token;
168
+        self.next_ping = Instant::now() + KEEPALIVE;
169
+        self.pong_deadline = None;
170
+        Ok(())
171
+    }
172
+
173
+    /// Replaces the set of enabled notification topics.
174
+    pub async fn set_topics(&mut self, topics: &[&str]) -> Result<(), CourierError> {
175
+        let hashes = topics
176
+            .iter()
177
+            .map(|s| Sha1::digest(s.as_bytes()).into())
178
+            .collect::<Vec<_>>();
179
+        Message::Filter {
180
+            token: &self.token,
181
+            topics: &hashes,
182
+        }
183
+        .write(&mut self.stream)
184
+        .await?;
185
+        self.topics = hashes;
186
+        Ok(())
187
+    }
188
+
189
+    /// Receives and acknowledges the next notification, driving keepalive while
190
+    /// waiting. Reconnect after errors or cancellation during a protocol write.
191
+    pub async fn receive(&mut self) -> Result<Notification, CourierError> {
192
+        loop {
193
+            let deadline = self.pong_deadline.unwrap_or(self.next_ping);
194
+            let frame = tokio::select! {
195
+                frame = self.reader.read(&mut self.stream) => frame?,
196
+                _ = sleep_until(deadline) => {
197
+                    if self.pong_deadline.is_some() { return Err(CourierError::Timeout); }
198
+                    Message::Ping.write(&mut self.stream).await?;
199
+                    self.pong_deadline = Some(Instant::now() + TIMEOUT);
200
+                    continue;
201
+                }
202
+            };
203
+            match frame.command() {
204
+                Command::Notification => {
205
+                    let id = u32::from_be_bytes(
206
+                        frame
207
+                            .required(4)?
208
+                            .try_into()
209
+                            .map_err(|_| CourierError::InvalidField(4))?,
210
+                    );
211
+                    let topic = frame
212
+                        .required(2)?
213
+                        .try_into()
214
+                        .map_err(|_| CourierError::InvalidField(2))?;
215
+                    let token = frame.get(1).unwrap_or(self.token.as_bytes());
216
+                    if token != self.token.as_bytes() {
217
+                        return Err(CourierError::TokenMismatch);
218
+                    }
219
+                    // Validate the payload before acknowledging it.
220
+                    frame.required(3)?;
221
+                    Message::Ack {
222
+                        token: &self.token,
223
+                        id,
224
+                    }
225
+                    .write(&mut self.stream)
226
+                    .await?;
227
+                    return Ok(Notification {
228
+                        id,
229
+                        topic,
230
+                        payload: frame.into_field(3)?,
231
+                    });
232
+                }
233
+                Command::Ping => Message::Pong.write(&mut self.stream).await?,
234
+                Command::Pong => {
235
+                    self.pong_deadline = None;
236
+                    self.next_ping = Instant::now() + KEEPALIVE;
237
+                }
238
+                _ => {}
239
+            }
240
+        }
241
+    }
242
+
243
+    pub async fn close(mut self) -> io::Result<()> {
244
+        timeout(TIMEOUT, self.stream.shutdown())
245
+            .await
246
+            .map_err(|_| io::ErrorKind::TimedOut)?
247
+    }
248
+}
249
+
250
+async fn handshake(
251
+    client: &Client,
252
+    identity: &PushIdentity,
253
+    previous: Option<&PushToken>,
254
+) -> Result<(TlsStream<TcpStream>, FrameReader, PushToken), ConnectError> {
255
+    let body = client
256
+        .get("https://init.push.apple.com/bag")
257
+        .send()
258
+        .await?
259
+        .error_for_status()?
260
+        .bytes()
261
+        .await?;
262
+    let mut bag: Dictionary = plist::from_bytes(&body)?;
263
+    if let Some(Value::Data(data)) = bag.get("bag") {
264
+        bag = plist::from_bytes(data)?;
265
+    }
266
+    let host = bag
267
+        .get("APNSCourierHostname")
268
+        .and_then(Value::as_string)
269
+        .ok_or(ConnectError::Configuration("APNSCourierHostname"))?;
270
+    let verified = bag
271
+        .get("APNSVerifiedCourierHostname")
272
+        .and_then(Value::as_string)
273
+        .unwrap_or(host);
274
+    let count = bag
275
+        .get("APNSCourierHostcount")
276
+        .and_then(Value::as_unsigned_integer)
277
+        .filter(|count| (1..=1000).contains(count))
278
+        .ok_or(ConnectError::Configuration("APNSCourierHostcount"))?;
279
+    let target = format!("{}-{host}", 1 + u64::from(OsRng.next_u32()) % count);
280
+    let server_name = ServerName::try_from(verified.to_owned())?;
281
+    let mut roots = RootCertStore::empty();
282
+    roots.add(CertificateDer::from_slice(include_bytes!(
283
+        "../certs/AppleRootCA.der"
284
+    )))?;
285
+    let mut config = ClientConfig::builder_with_provider(Arc::new(ring::default_provider()))
286
+        .with_safe_default_protocol_versions()?
287
+        .with_root_certificates(roots)
288
+        .with_no_client_auth();
289
+    // Select the signed Connect handshake without enabling packed APS frames.
290
+    config.alpn_protocols = vec![b"apns-security-v3".to_vec()];
291
+    let socket = TcpStream::connect((target.as_str(), 5223)).await?;
292
+    let mut stream = TlsConnector::from(Arc::new(config))
293
+        .connect(server_name, socket)
294
+        .await?;
295
+
296
+    let millis = SystemTime::now().duration_since(UNIX_EPOCH)?.as_millis() as u64;
297
+    // APS nonce: discriminator 0, big-endian Unix milliseconds, 8 random bytes.
298
+    let mut nonce = [0; 17];
299
+    nonce[1..9].copy_from_slice(&millis.to_be_bytes());
300
+    OsRng.fill_bytes(&mut nonce[9..]);
301
+    let raw_signature = sign_sha1(identity.private_key(), &nonce)?;
302
+    let mut signature = Vec::with_capacity(2 + raw_signature.len());
303
+    // Apple's nonce signer prefixes its RSA/SHA-1 signature with these bytes.
304
+    signature.extend_from_slice(&[1, 1]);
305
+    signature.extend_from_slice(&raw_signature);
306
+    Message::Connect {
307
+        previous,
308
+        certificate: identity.certificate(),
309
+        nonce: &nonce,
310
+        signature: &signature,
311
+    }
312
+    .write(&mut stream)
313
+    .await?;
314
+    let mut reader = FrameReader::default();
315
+    let reply = reader.read(&mut stream).await?;
316
+    if reply.command() != Command::Connected {
317
+        return Err(CourierError::UnexpectedCommand(reply.command().code()).into());
318
+    }
319
+    let [status] = reply.required(1)? else {
320
+        return Err(CourierError::InvalidField(1).into());
321
+    };
322
+    if *status != 0 {
323
+        return Err(ConnectError::Rejected(*status));
324
+    }
325
+    let token = match reply.get(3) {
326
+        Some(bytes) => PushToken(
327
+            bytes
328
+                .try_into()
329
+                .map_err(|_| CourierError::InvalidField(3))?,
330
+        ),
331
+        None => previous.cloned().ok_or(CourierError::MissingField(3))?,
332
+    };
333
+    Message::SetActive.write(&mut stream).await?;
334
+    Ok((stream, reader, token))
335
+}
... ...
@@ -0,0 +1,17 @@
1
+//! Device activation and connections to the Apple Push Service.
2
+//!
3
+//! Activation yields a device identity. The courier handshake then yields a
4
+//! push token. Neither operation requires an Apple account or anisette.
5
+
6
+mod activation;
7
+mod connection;
8
+mod protocol;
9
+mod windows_signer;
10
+
11
+pub use activation::{
12
+    ActivationDevice, ActivationError, ActivationSignature, ActivationSigner, IdentityError,
13
+    PushIdentity, activate,
14
+};
15
+pub use connection::{ConnectError, Notification, PushConnection, PushToken};
16
+pub use protocol::CourierError;
17
+pub use windows_signer::WindowsActivationSigner;
... ...
@@ -0,0 +1,259 @@
1
+use crate::PushToken;
2
+use bytes::{Bytes, BytesMut};
3
+use std::ops::Range;
4
+use thiserror::Error;
5
+use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};
6
+
7
+pub(crate) const TIMEOUT: std::time::Duration = std::time::Duration::from_secs(30);
8
+
9
+const MAX_FRAME_SIZE: usize = 1024 * 1024;
10
+
11
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
12
+pub(crate) enum Command {
13
+    Connect,
14
+    Connected,
15
+    Filter,
16
+    Notification,
17
+    Ack,
18
+    Ping,
19
+    Pong,
20
+    SetState,
21
+    Unknown(u8),
22
+}
23
+
24
+impl Command {
25
+    pub fn code(self) -> u8 {
26
+        match self {
27
+            Self::Connect => 7,
28
+            Self::Connected => 8,
29
+            Self::Filter => 9,
30
+            Self::Notification => 10,
31
+            Self::Ack => 11,
32
+            Self::Ping => 12,
33
+            Self::Pong => 13,
34
+            Self::SetState => 20,
35
+            Self::Unknown(code) => code,
36
+        }
37
+    }
38
+}
39
+
40
+/// Outgoing messages borrow their fields and encode directly into one wire buffer.
41
+pub(crate) enum Message<'a> {
42
+    Connect {
43
+        previous: Option<&'a PushToken>,
44
+        certificate: &'a [u8],
45
+        nonce: &'a [u8; 17],
46
+        signature: &'a [u8],
47
+    },
48
+    Filter {
49
+        token: &'a PushToken,
50
+        topics: &'a [[u8; 20]],
51
+    },
52
+    Ack {
53
+        token: &'a PushToken,
54
+        id: u32,
55
+    },
56
+    Ping,
57
+    Pong,
58
+    SetActive,
59
+}
60
+
61
+impl Message<'_> {
62
+    pub async fn write(self, stream: &mut (impl AsyncWrite + Unpin)) -> Result<(), CourierError> {
63
+        let frame = match self {
64
+            Self::Connect {
65
+                previous,
66
+                certificate,
67
+                nonce,
68
+                signature,
69
+            } => {
70
+                let mut frame = Frame::new(Command::Connect);
71
+                if let Some(token) = previous {
72
+                    frame.push(1, token.as_bytes())?;
73
+                }
74
+                frame.push(2, [1])?; // Connect state; Apple's disconnect path sends 2.
75
+                // Presence flags used by rustpush. The Windows client sends 0x4c
76
+                // on connect and 0x48 for presence; individual bits are unverified.
77
+                frame.push(5, 0x41u32.to_be_bytes())?;
78
+                frame.push(12, certificate)?;
79
+                frame.push(13, nonce)?;
80
+                frame.push(14, signature)?;
81
+                // Version-like field used by rustpush; this Windows build sends 5.
82
+                // Its precise semantics are not established.
83
+                frame.push(16, 9u16.to_be_bytes())?;
84
+                frame
85
+            }
86
+            Self::Filter { token, topics } => {
87
+                let mut frame = Frame::new(Command::Filter);
88
+                frame.push(1, token.as_bytes())?;
89
+                for topic in topics {
90
+                    frame.push(2, topic)?;
91
+                }
92
+                frame
93
+            }
94
+            Self::Ack { token, id } => {
95
+                let mut frame = Frame::new(Command::Ack);
96
+                frame.push(1, token.as_bytes())?;
97
+                frame.push(4, id.to_be_bytes())?;
98
+                frame.push(8, [0])?; // Success.
99
+                frame
100
+            }
101
+            Self::Ping => Frame::new(Command::Ping),
102
+            Self::Pong => Frame::new(Command::Pong),
103
+            Self::SetActive => {
104
+                let mut frame = Frame::new(Command::SetState);
105
+                frame.push(1, [1])?;
106
+                // rustpush's state interval. INT_MAX is observed; "infinite" is unverified.
107
+                frame.push(2, 0x7fff_ffffu32.to_be_bytes())?;
108
+                frame
109
+            }
110
+        };
111
+        frame.write(stream).await
112
+    }
113
+}
114
+
115
+#[derive(Debug, Error)]
116
+pub enum CourierError {
117
+    #[error("Courier I/O failed: {0}")]
118
+    Io(#[from] std::io::Error),
119
+    #[error("APS frame exceeds the size limit")]
120
+    FrameTooLarge,
121
+    #[error("APS field {0} exceeds the wire size limit")]
122
+    FieldTooLarge(u8),
123
+    #[error("Truncated APS field")]
124
+    TruncatedField,
125
+    #[error("Missing APS field {0}")]
126
+    MissingField(u8),
127
+    #[error("Invalid APS field {0}")]
128
+    InvalidField(u8),
129
+    #[error("Unexpected APS command {0}")]
130
+    UnexpectedCommand(u8),
131
+    #[error("The notification belongs to another push token")]
132
+    TokenMismatch,
133
+    #[error("Courier operation timed out")]
134
+    Timeout,
135
+}
136
+
137
+// command:u8, length:u32, then (id:u8, length:u16, value), all big endian.
138
+// Fields borrow the wire buffer instead of allocating a Vec for each TLV.
139
+pub(crate) struct Frame {
140
+    bytes: BytesMut,
141
+}
142
+
143
+impl Frame {
144
+    fn new(command: Command) -> Self {
145
+        Self {
146
+            bytes: BytesMut::from(&[command.code(), 0, 0, 0, 0][..]),
147
+        }
148
+    }
149
+
150
+    pub fn command(&self) -> Command {
151
+        match self.bytes[0] {
152
+            7 => Command::Connect,
153
+            8 => Command::Connected,
154
+            9 => Command::Filter,
155
+            10 => Command::Notification,
156
+            11 => Command::Ack,
157
+            12 => Command::Ping,
158
+            13 => Command::Pong,
159
+            20 => Command::SetState,
160
+            code => Command::Unknown(code),
161
+        }
162
+    }
163
+
164
+    fn push(&mut self, id: u8, value: impl AsRef<[u8]>) -> Result<(), CourierError> {
165
+        let value = value.as_ref();
166
+        let size = u16::try_from(value.len()).map_err(|_| CourierError::FieldTooLarge(id))?;
167
+        if self.bytes.len() - 5 + 3 + value.len() > MAX_FRAME_SIZE {
168
+            return Err(CourierError::FrameTooLarge);
169
+        }
170
+        self.bytes.extend_from_slice(&[id]);
171
+        self.bytes.extend_from_slice(&size.to_be_bytes());
172
+        self.bytes.extend_from_slice(value);
173
+        let length = (self.bytes.len() - 5) as u32;
174
+        self.bytes[1..5].copy_from_slice(&length.to_be_bytes());
175
+        Ok(())
176
+    }
177
+
178
+    fn field_range(&self, id: u8) -> Option<Range<usize>> {
179
+        let mut offset = 5;
180
+        while offset < self.bytes.len() {
181
+            let key = self.bytes[offset];
182
+            let size =
183
+                u16::from_be_bytes([self.bytes[offset + 1], self.bytes[offset + 2]]) as usize;
184
+            offset += 3;
185
+            if key == id {
186
+                return Some(offset..offset + size);
187
+            }
188
+            offset += size;
189
+        }
190
+        None
191
+    }
192
+
193
+    pub fn get(&self, id: u8) -> Option<&[u8]> {
194
+        self.field_range(id).map(|range| &self.bytes[range])
195
+    }
196
+
197
+    pub fn required(&self, id: u8) -> Result<&[u8], CourierError> {
198
+        self.get(id).ok_or(CourierError::MissingField(id))
199
+    }
200
+
201
+    pub fn into_field(self, id: u8) -> Result<Bytes, CourierError> {
202
+        let range = self.field_range(id).ok_or(CourierError::MissingField(id))?;
203
+        Ok(self.bytes.freeze().slice(range))
204
+    }
205
+
206
+    async fn write(&self, stream: &mut (impl AsyncWrite + Unpin)) -> Result<(), CourierError> {
207
+        tokio::time::timeout(TIMEOUT, async {
208
+            stream.write_all(&self.bytes).await?;
209
+            stream.flush().await
210
+        })
211
+        .await
212
+        .map_err(|_| CourierError::Timeout)??;
213
+        Ok(())
214
+    }
215
+}
216
+
217
+#[derive(Default)]
218
+pub(crate) struct FrameReader {
219
+    // Retained when keepalive interrupts a read.
220
+    buffer: BytesMut,
221
+}
222
+
223
+impl FrameReader {
224
+    pub async fn read(
225
+        &mut self,
226
+        stream: &mut (impl AsyncRead + Unpin),
227
+    ) -> Result<Frame, CourierError> {
228
+        loop {
229
+            if self.buffer.len() >= 5 {
230
+                let length = u32::from_be_bytes(self.buffer[1..5].try_into().unwrap()) as usize;
231
+                if length > MAX_FRAME_SIZE {
232
+                    return Err(CourierError::FrameTooLarge);
233
+                }
234
+                if self.buffer.len() >= length + 5 {
235
+                    let mut offset = 5;
236
+                    while offset < length + 5 {
237
+                        if offset + 3 > length + 5 {
238
+                            return Err(CourierError::TruncatedField);
239
+                        }
240
+                        let size =
241
+                            u16::from_be_bytes([self.buffer[offset + 1], self.buffer[offset + 2]])
242
+                                as usize;
243
+                        offset += 3 + size;
244
+                        if offset > length + 5 {
245
+                            return Err(CourierError::TruncatedField);
246
+                        }
247
+                    }
248
+                    return Ok(Frame {
249
+                        bytes: self.buffer.split_to(length + 5),
250
+                    });
251
+                }
252
+            }
253
+            self.buffer.reserve(4096);
254
+            if stream.read_buf(&mut self.buffer).await? == 0 {
255
+                return Err(std::io::Error::from(std::io::ErrorKind::UnexpectedEof).into());
256
+            }
257
+        }
258
+    }
259
+}
... ...
@@ -0,0 +1,52 @@
1
+mod constants;
2
+
3
+use crate::{ActivationSignature, ActivationSigner, activation::sign_sha1};
4
+use constants::{CERTIFICATE_AUTHORITY_CHAIN, IDENTITIES, PUBLIC_EXPONENT};
5
+use rsa::{
6
+    BigUint, RsaPrivateKey,
7
+    rand_core::{OsRng, RngCore},
8
+};
9
+
10
+/// Signs activation requests using the embedded Windows activation identities.
11
+pub struct WindowsActivationSigner {
12
+    private_key: RsaPrivateKey,
13
+    certificate_chain: Vec<u8>,
14
+}
15
+
16
+impl WindowsActivationSigner {
17
+    /// Selects one of the ten identities, as Apple's Windows client does.
18
+    pub fn new() -> Self {
19
+        let identity = &IDENTITIES[OsRng.next_u32() as usize % IDENTITIES.len()];
20
+        let private_key = RsaPrivateKey::from_p_q(
21
+            BigUint::from_bytes_be(&identity.p),
22
+            BigUint::from_bytes_be(&identity.q),
23
+            PUBLIC_EXPONENT.into(),
24
+        )
25
+        .expect("embedded activation primes must form a valid RSA key");
26
+        let mut certificate_chain =
27
+            Vec::with_capacity(identity.certificate.len() + CERTIFICATE_AUTHORITY_CHAIN.len());
28
+        certificate_chain.extend_from_slice(identity.certificate);
29
+        certificate_chain.extend_from_slice(CERTIFICATE_AUTHORITY_CHAIN);
30
+        Self {
31
+            private_key,
32
+            certificate_chain,
33
+        }
34
+    }
35
+}
36
+
37
+impl Default for WindowsActivationSigner {
38
+    fn default() -> Self {
39
+        Self::new()
40
+    }
41
+}
42
+
43
+impl ActivationSigner for WindowsActivationSigner {
44
+    type Error = rsa::Error;
45
+
46
+    fn sign(&self, xml: &[u8]) -> Result<ActivationSignature, Self::Error> {
47
+        Ok(ActivationSignature {
48
+            signature: sign_sha1(&self.private_key, xml)?,
49
+            certificate_chain: self.certificate_chain.clone(),
50
+        })
51
+    }
52
+}
... ...
@@ -0,0 +1,850 @@
1
+// Shared activation identities from APSDaemon_main.dll, iCloud 15.10.39.0 x64.
2
+// See ../../docs/windows-signing.md for provenance and decoding details.
3
+// Only p and q are needed; rsa reconstructs the remaining CRT components.
4
+
5
+pub(super) struct SigningIdentity {
6
+    pub p: [u8; 64],
7
+    pub q: [u8; 64],
8
+    pub certificate: &'static [u8],
9
+}
10
+
11
+pub(super) const PUBLIC_EXPONENT: u32 = 65537;
12
+
13
+pub(super) static IDENTITIES: [SigningIdentity; 10] = [
14
+    // APN-Win identity 000001.
15
+    SigningIdentity {
16
+        p: [
17
+            0xe2, 0x3a, 0xc7, 0xac, 0xca, 0xaf, 0xe6, 0x2d, 0x20, 0x82, 0x39, 0x46, 0xa6, 0xd7,
18
+            0xf4, 0xf9, 0xa7, 0x2d, 0xd4, 0x0e, 0xbb, 0xed, 0x56, 0xf1, 0x39, 0x3c, 0x2b, 0x86,
19
+            0x3d, 0x57, 0x65, 0xda, 0xec, 0x69, 0x88, 0xd1, 0x4e, 0x7e, 0xd2, 0x52, 0xe2, 0x31,
20
+            0x75, 0x07, 0x38, 0x5f, 0xd7, 0x6d, 0x5a, 0xc5, 0xb5, 0x0d, 0xd3, 0x57, 0x05, 0xc0,
21
+            0x62, 0xf6, 0x25, 0xae, 0x84, 0x89, 0x6a, 0x29,
22
+        ],
23
+        q: [
24
+            0xcf, 0xf3, 0x26, 0x9e, 0x30, 0x2d, 0x0b, 0xd4, 0x2a, 0x20, 0x16, 0x91, 0xcf, 0x01,
25
+            0xb9, 0x38, 0x84, 0x01, 0xb9, 0xe3, 0xd8, 0xc5, 0x6f, 0x48, 0xb4, 0x53, 0x8e, 0x51,
26
+            0xb4, 0x29, 0xb2, 0xab, 0x80, 0x91, 0x66, 0x2f, 0x39, 0x2a, 0xd8, 0xdc, 0x2c, 0xd6,
27
+            0x23, 0xdd, 0x34, 0xce, 0x22, 0x34, 0x78, 0xd4, 0x19, 0xf5, 0x06, 0x32, 0x8e, 0x6a,
28
+            0xc2, 0xb0, 0x8a, 0x71, 0xfd, 0x77, 0x77, 0xc3,
29
+        ],
30
+        certificate: &[
31
+            0x30, 0x82, 0x02, 0xc5, 0x30, 0x82, 0x02, 0x2e, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
32
+            0x0d, 0x33, 0x33, 0xaf, 0x10, 0x10, 0x20, 0xaf, 0x00, 0x01, 0xaf, 0x00, 0x00, 0x01,
33
+            0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05,
34
+            0x00, 0x30, 0x7b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
35
+            0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41,
36
+            0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06,
37
+            0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65,
38
+            0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
39
+            0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x2f, 0x30, 0x2d, 0x06, 0x03, 0x55,
40
+            0x04, 0x03, 0x13, 0x26, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x46, 0x61, 0x69, 0x72,
41
+            0x50, 0x6c, 0x61, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
42
+            0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79,
43
+            0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x31, 0x30, 0x32, 0x30, 0x30, 0x30, 0x30, 0x32,
44
+            0x30, 0x31, 0x5a, 0x17, 0x0d, 0x31, 0x35, 0x31, 0x30, 0x31, 0x39, 0x30, 0x30, 0x30,
45
+            0x32, 0x30, 0x31, 0x5a, 0x30, 0x68, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
46
+            0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
47
+            0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x17,
48
+            0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0e, 0x41, 0x70, 0x70, 0x6c, 0x65,
49
+            0x20, 0x46, 0x61, 0x69, 0x72, 0x50, 0x6c, 0x61, 0x79, 0x31, 0x2b, 0x30, 0x29, 0x06,
50
+            0x03, 0x55, 0x04, 0x03, 0x13, 0x22, 0x41, 0x50, 0x4e, 0x2d, 0x57, 0x69, 0x6e, 0x2e,
51
+            0x33, 0x33, 0x33, 0x33, 0x41, 0x46, 0x31, 0x30, 0x31, 0x30, 0x32, 0x30, 0x41, 0x46,
52
+            0x30, 0x30, 0x30, 0x31, 0x41, 0x46, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x81,
53
+            0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
54
+            0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xb7,
55
+            0xc4, 0x67, 0x60, 0xc5, 0x66, 0x57, 0x0a, 0xb2, 0xb6, 0x4e, 0x88, 0x6e, 0xab, 0xb5,
56
+            0x40, 0x47, 0x92, 0x5f, 0x01, 0x67, 0xa1, 0x9c, 0x29, 0xa7, 0x4d, 0x56, 0x0d, 0x7f,
57
+            0x05, 0x8d, 0x1c, 0xff, 0x95, 0x8a, 0x26, 0x78, 0xa8, 0xb2, 0xf1, 0xd4, 0x86, 0x55,
58
+            0xc6, 0x09, 0x5a, 0x1c, 0xe8, 0x31, 0x20, 0x68, 0x5b, 0x55, 0x4d, 0x1c, 0x81, 0x12,
59
+            0x87, 0x2f, 0x2f, 0x00, 0x6d, 0x6e, 0x18, 0xab, 0xb7, 0xdd, 0xf7, 0x8c, 0x92, 0x6d,
60
+            0x7f, 0xbb, 0x69, 0x8d, 0x7c, 0x35, 0xbf, 0x8e, 0xcb, 0x6f, 0x4c, 0x27, 0x06, 0x2c,
61
+            0x72, 0xa8, 0x92, 0xe7, 0x4f, 0x0a, 0xa7, 0xe3, 0x6d, 0xcf, 0x9b, 0xff, 0xd2, 0xb4,
62
+            0x84, 0xc1, 0x2b, 0x52, 0xd7, 0x8a, 0xd0, 0xeb, 0x72, 0x65, 0x3c, 0x9a, 0xe7, 0x2b,
63
+            0xaa, 0x83, 0x4c, 0x90, 0x5d, 0xbc, 0x95, 0x6c, 0x30, 0x33, 0x6e, 0xb3, 0x13, 0xec,
64
+            0x3b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x60, 0x30, 0x5e, 0x30, 0x0e, 0x06, 0x03,
65
+            0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x03, 0xb8, 0x30, 0x0c,
66
+            0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d,
67
+            0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xdd, 0x56, 0x61, 0x8e, 0x48,
68
+            0xe7, 0x51, 0x79, 0x9f, 0x85, 0xac, 0x1e, 0xb3, 0xf0, 0x98, 0x7a, 0xdc, 0xf3, 0x26,
69
+            0x7a, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
70
+            0xfa, 0x0d, 0xd4, 0x11, 0x91, 0x1b, 0xe6, 0xb2, 0x4e, 0x1e, 0x06, 0x49, 0x94, 0x11,
71
+            0xdd, 0x63, 0x62, 0x07, 0x59, 0x64, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
72
+            0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x2a, 0xae, 0xec,
73
+            0x81, 0xc7, 0x8d, 0xa5, 0xf5, 0x51, 0xb4, 0xee, 0x82, 0x0f, 0xd4, 0xa7, 0x08, 0x83,
74
+            0xba, 0x48, 0x04, 0x6d, 0x85, 0xbe, 0x69, 0x9a, 0xfa, 0x73, 0x59, 0x03, 0xe0, 0x53,
75
+            0xc1, 0xad, 0x54, 0x9b, 0x90, 0x16, 0x5e, 0xf3, 0x9e, 0x5d, 0xa2, 0x7b, 0x75, 0xd9,
76
+            0x85, 0x7b, 0xeb, 0x9a, 0xeb, 0x43, 0xf1, 0x24, 0x59, 0x05, 0x0b, 0xc0, 0x03, 0x0b,
77
+            0xb1, 0x99, 0x75, 0xab, 0x71, 0xd8, 0x7c, 0x4e, 0x02, 0x92, 0xf1, 0x54, 0x95, 0x89,
78
+            0x27, 0x75, 0x38, 0xf5, 0x96, 0xcc, 0xc0, 0xa8, 0x76, 0x6c, 0xf3, 0xb6, 0xa3, 0xfe,
79
+            0x9d, 0x1f, 0x92, 0x1d, 0x77, 0x1c, 0xe0, 0xc8, 0x39, 0x60, 0x25, 0xfc, 0x35, 0xb3,
80
+            0x0c, 0x95, 0x0c, 0xf2, 0x90, 0xf5, 0x4f, 0x23, 0xd0, 0xea, 0x78, 0x8f, 0x55, 0x0c,
81
+            0x9e, 0xc7, 0x76, 0x6e, 0x71, 0x05, 0xec, 0x88, 0x6c, 0x5f, 0x90, 0xb2, 0xb3,
82
+        ],
83
+    },
84
+    // APN-Win identity 000002.
85
+    SigningIdentity {
86
+        p: [
87
+            0xfd, 0xce, 0x1a, 0x02, 0x08, 0x1e, 0x5f, 0xb3, 0x0d, 0xd7, 0x7b, 0x50, 0x92, 0xd4,
88
+            0xde, 0xc5, 0x9a, 0x2b, 0x47, 0x8d, 0xd6, 0xff, 0x24, 0x27, 0x04, 0x5a, 0x53, 0xe4,
89
+            0xa0, 0x98, 0xad, 0xdd, 0xd6, 0x08, 0xc6, 0x96, 0x3e, 0x36, 0x81, 0x19, 0xac, 0x7c,
90
+            0x6b, 0x37, 0x5d, 0xfe, 0x9b, 0xa6, 0x0b, 0xba, 0x11, 0x56, 0xf0, 0x6d, 0xff, 0x1f,
91
+            0x1a, 0x79, 0x1a, 0x51, 0x13, 0xb8, 0x54, 0x37,
92
+        ],
93
+        q: [
94
+            0xf5, 0xea, 0x55, 0x5b, 0x42, 0x99, 0x5f, 0x92, 0x2b, 0x38, 0x9e, 0xa3, 0x85, 0x90,
95
+            0x68, 0x37, 0x95, 0xb5, 0x1b, 0x5b, 0xa2, 0x87, 0xcb, 0x48, 0xb8, 0x72, 0x9f, 0xa3,
96
+            0x94, 0x4a, 0xfa, 0x0b, 0x65, 0x4a, 0xa4, 0x11, 0xff, 0xfa, 0xaf, 0x50, 0x29, 0x95,
97
+            0xf2, 0x59, 0x2c, 0xb9, 0x0d, 0x98, 0x9a, 0xb3, 0xc5, 0xbd, 0x31, 0xee, 0x15, 0x67,
98
+            0x83, 0xbb, 0x0e, 0x75, 0x6a, 0x54, 0xdb, 0xb5,
99
+        ],
100
+        certificate: &[
101
+            0x30, 0x82, 0x02, 0xc5, 0x30, 0x82, 0x02, 0x2e, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
102
+            0x0d, 0x33, 0x33, 0xaf, 0x10, 0x10, 0x20, 0xaf, 0x00, 0x01, 0xaf, 0x00, 0x00, 0x02,
103
+            0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05,
104
+            0x00, 0x30, 0x7b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
105
+            0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41,
106
+            0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06,
107
+            0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65,
108
+            0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
109
+            0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x2f, 0x30, 0x2d, 0x06, 0x03, 0x55,
110
+            0x04, 0x03, 0x13, 0x26, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x46, 0x61, 0x69, 0x72,
111
+            0x50, 0x6c, 0x61, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
112
+            0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79,
113
+            0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x31, 0x30, 0x32, 0x30, 0x30, 0x30, 0x30, 0x32,
114
+            0x30, 0x32, 0x5a, 0x17, 0x0d, 0x31, 0x35, 0x31, 0x30, 0x31, 0x39, 0x30, 0x30, 0x30,
115
+            0x32, 0x30, 0x32, 0x5a, 0x30, 0x68, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
116
+            0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
117
+            0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x17,
118
+            0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0e, 0x41, 0x70, 0x70, 0x6c, 0x65,
119
+            0x20, 0x46, 0x61, 0x69, 0x72, 0x50, 0x6c, 0x61, 0x79, 0x31, 0x2b, 0x30, 0x29, 0x06,
120
+            0x03, 0x55, 0x04, 0x03, 0x13, 0x22, 0x41, 0x50, 0x4e, 0x2d, 0x57, 0x69, 0x6e, 0x2e,
121
+            0x33, 0x33, 0x33, 0x33, 0x41, 0x46, 0x31, 0x30, 0x31, 0x30, 0x32, 0x30, 0x41, 0x46,
122
+            0x30, 0x30, 0x30, 0x31, 0x41, 0x46, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, 0x30, 0x81,
123
+            0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
124
+            0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xf3,
125
+            0xce, 0x91, 0xe7, 0xa0, 0x8d, 0x9a, 0x67, 0x45, 0xd6, 0x5d, 0xf3, 0xe8, 0xa3, 0x4f,
126
+            0xca, 0x63, 0xfd, 0xf0, 0x7c, 0x8d, 0xae, 0xfe, 0x8d, 0xdf, 0x52, 0x77, 0x1b, 0x6f,
127
+            0x22, 0x51, 0xfa, 0x1d, 0x01, 0xae, 0x70, 0x5f, 0x90, 0x15, 0x2d, 0xf6, 0xd3, 0x31,
128
+            0x17, 0xf0, 0xb1, 0xb8, 0x48, 0xd3, 0xf9, 0xa7, 0x1d, 0x58, 0x48, 0xbf, 0xf0, 0x2f,
129
+            0x50, 0x9b, 0x1e, 0xa9, 0x65, 0x62, 0x5d, 0xf2, 0xd4, 0xfe, 0xb4, 0x3d, 0xcd, 0x32,
130
+            0x6d, 0x75, 0xab, 0x50, 0xd0, 0x88, 0xbe, 0xef, 0x13, 0x42, 0xb3, 0xa1, 0xa6, 0x97,
131
+            0x6e, 0xd7, 0x10, 0xb0, 0xd7, 0xfb, 0xda, 0x3b, 0x8b, 0xba, 0xbb, 0xdd, 0x5e, 0x36,
132
+            0x67, 0x94, 0x8d, 0xca, 0x4d, 0xc8, 0x34, 0xb6, 0x72, 0xf7, 0xe1, 0xdb, 0xfe, 0x46,
133
+            0x58, 0x07, 0xcc, 0xfd, 0x7e, 0x67, 0x46, 0x46, 0xee, 0x41, 0xaf, 0x09, 0x6a, 0x97,
134
+            0xe3, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x60, 0x30, 0x5e, 0x30, 0x0e, 0x06, 0x03,
135
+            0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x03, 0xb8, 0x30, 0x0c,
136
+            0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d,
137
+            0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xa4, 0xd6, 0xfe, 0xac, 0x1f,
138
+            0x91, 0xe9, 0xe0, 0x7b, 0x17, 0x15, 0x88, 0xda, 0xcd, 0x43, 0xdc, 0x48, 0x22, 0x52,
139
+            0xba, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
140
+            0xfa, 0x0d, 0xd4, 0x11, 0x91, 0x1b, 0xe6, 0xb2, 0x4e, 0x1e, 0x06, 0x49, 0x94, 0x11,
141
+            0xdd, 0x63, 0x62, 0x07, 0x59, 0x64, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
142
+            0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x80, 0x3d, 0x5c,
143
+            0xb1, 0x79, 0xb4, 0x2e, 0x24, 0xd4, 0x75, 0x9f, 0xe4, 0x5c, 0x8f, 0x3a, 0x4c, 0x16,
144
+            0xa7, 0x2a, 0x74, 0xbd, 0xce, 0x5b, 0xca, 0x75, 0xb4, 0x02, 0x90, 0xd6, 0xd3, 0xd2,
145
+            0xfb, 0x4d, 0xb8, 0xa0, 0xc6, 0xa4, 0xd6, 0x05, 0x39, 0x15, 0xaa, 0x69, 0x54, 0x79,
146
+            0xc7, 0xe1, 0xc6, 0x3e, 0x1a, 0xb0, 0xd4, 0xaf, 0x39, 0xb8, 0x22, 0xef, 0xc3, 0xd6,
147
+            0xf7, 0xaf, 0x45, 0xb5, 0xe2, 0xda, 0x5b, 0x3c, 0xb6, 0xc8, 0x8c, 0x0d, 0xd4, 0xb5,
148
+            0xc9, 0x57, 0xa0, 0xc4, 0x7c, 0xaf, 0x9e, 0x72, 0x60, 0x9b, 0xaa, 0xf0, 0xff, 0x2f,
149
+            0x3e, 0x62, 0xf8, 0x3c, 0xb4, 0xfe, 0xe2, 0x58, 0x00, 0xeb, 0x16, 0x21, 0x36, 0x47,
150
+            0x6d, 0x60, 0x37, 0x9c, 0x7a, 0xe9, 0xb1, 0x58, 0x47, 0x53, 0x76, 0x2e, 0x3e, 0x6e,
151
+            0x91, 0xde, 0x92, 0x1e, 0xea, 0x3f, 0xd4, 0x2c, 0xb9, 0xc3, 0x67, 0x2f, 0x07,
152
+        ],
153
+    },
154
+    // APN-Win identity 000003.
155
+    SigningIdentity {
156
+        p: [
157
+            0xee, 0x6e, 0x95, 0xa0, 0x19, 0x46, 0xd8, 0x80, 0xc5, 0x7d, 0x15, 0x56, 0x90, 0x5f,
158
+            0xc5, 0x2c, 0x4a, 0x55, 0xb5, 0xee, 0x85, 0x0d, 0xb8, 0x46, 0x00, 0xdc, 0xf9, 0xd6,
159
+            0xaf, 0xc8, 0xdf, 0xa1, 0x79, 0x9f, 0xff, 0xc2, 0x6e, 0x84, 0xa8, 0xcb, 0x9f, 0x50,
160
+            0xa8, 0x41, 0xeb, 0xea, 0xf8, 0xd2, 0xb3, 0xe0, 0x22, 0x16, 0x29, 0x84, 0xc0, 0x55,
161
+            0x3b, 0xef, 0xb1, 0xef, 0xa4, 0xbc, 0x4c, 0x07,
162
+        ],
163
+        q: [
164
+            0xd6, 0x6d, 0xcc, 0x1c, 0x89, 0xf3, 0x37, 0x27, 0xef, 0x93, 0xde, 0x23, 0x39, 0x6d,
165
+            0xea, 0x18, 0xb6, 0x0b, 0xe1, 0x63, 0x27, 0x26, 0x89, 0x0b, 0x69, 0xaa, 0xa8, 0x0f,
166
+            0xc6, 0x97, 0xc3, 0x8c, 0xf3, 0x7a, 0xd0, 0xfd, 0x44, 0x97, 0xae, 0x2c, 0x57, 0x33,
167
+            0x27, 0xc5, 0xcd, 0xb7, 0x4d, 0xe6, 0x18, 0xc3, 0xf1, 0xd1, 0xc0, 0x98, 0x51, 0xc5,
168
+            0xd0, 0xfe, 0xc5, 0xcb, 0x4f, 0x47, 0xad, 0xe5,
169
+        ],
170
+        certificate: &[
171
+            0x30, 0x82, 0x02, 0xc5, 0x30, 0x82, 0x02, 0x2e, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
172
+            0x0d, 0x33, 0x33, 0xaf, 0x10, 0x10, 0x20, 0xaf, 0x00, 0x01, 0xaf, 0x00, 0x00, 0x03,
173
+            0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05,
174
+            0x00, 0x30, 0x7b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
175
+            0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41,
176
+            0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06,
177
+            0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65,
178
+            0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
179
+            0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x2f, 0x30, 0x2d, 0x06, 0x03, 0x55,
180
+            0x04, 0x03, 0x13, 0x26, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x46, 0x61, 0x69, 0x72,
181
+            0x50, 0x6c, 0x61, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
182
+            0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79,
183
+            0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x31, 0x30, 0x32, 0x30, 0x30, 0x30, 0x30, 0x32,
184
+            0x30, 0x32, 0x5a, 0x17, 0x0d, 0x31, 0x35, 0x31, 0x30, 0x31, 0x39, 0x30, 0x30, 0x30,
185
+            0x32, 0x30, 0x32, 0x5a, 0x30, 0x68, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
186
+            0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
187
+            0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x17,
188
+            0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0e, 0x41, 0x70, 0x70, 0x6c, 0x65,
189
+            0x20, 0x46, 0x61, 0x69, 0x72, 0x50, 0x6c, 0x61, 0x79, 0x31, 0x2b, 0x30, 0x29, 0x06,
190
+            0x03, 0x55, 0x04, 0x03, 0x13, 0x22, 0x41, 0x50, 0x4e, 0x2d, 0x57, 0x69, 0x6e, 0x2e,
191
+            0x33, 0x33, 0x33, 0x33, 0x41, 0x46, 0x31, 0x30, 0x31, 0x30, 0x32, 0x30, 0x41, 0x46,
192
+            0x30, 0x30, 0x30, 0x31, 0x41, 0x46, 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, 0x30, 0x81,
193
+            0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
194
+            0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xc7,
195
+            0xb6, 0xb4, 0x44, 0x3e, 0x1b, 0xa2, 0x36, 0xb4, 0xd1, 0x00, 0x91, 0x4e, 0x58, 0xd5,
196
+            0x5c, 0x81, 0xe6, 0x56, 0x6e, 0x06, 0xee, 0x13, 0x15, 0x69, 0x3e, 0xe3, 0x57, 0xf6,
197
+            0x66, 0xbf, 0xf1, 0x30, 0xa8, 0xbd, 0xbd, 0xed, 0x50, 0xe2, 0xed, 0x46, 0xee, 0xcb,
198
+            0x64, 0x8a, 0x43, 0xbc, 0xdf, 0x47, 0x16, 0x41, 0x56, 0x70, 0x87, 0xd4, 0xa0, 0x66,
199
+            0x8a, 0x7d, 0xce, 0x48, 0x7c, 0x01, 0x8f, 0xa5, 0x5f, 0x9c, 0xa3, 0x23, 0x8d, 0x36,
200
+            0x94, 0x48, 0xe6, 0x38, 0x7d, 0x1b, 0xf4, 0x59, 0xce, 0xb3, 0x05, 0xed, 0x69, 0x43,
201
+            0x02, 0x68, 0xc2, 0x4e, 0x02, 0x9d, 0x9f, 0x0e, 0x94, 0x6a, 0xe6, 0x26, 0x57, 0x38,
202
+            0xab, 0x1e, 0xcd, 0xea, 0xc1, 0x94, 0x77, 0xf0, 0x30, 0x0d, 0xc4, 0xe9, 0x20, 0x7e,
203
+            0x40, 0xb8, 0x3b, 0x78, 0x96, 0xe8, 0xeb, 0x8c, 0xb9, 0x95, 0xed, 0xda, 0xc1, 0xbd,
204
+            0x43, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x60, 0x30, 0x5e, 0x30, 0x0e, 0x06, 0x03,
205
+            0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x03, 0xb8, 0x30, 0x0c,
206
+            0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d,
207
+            0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x28, 0xe6, 0xd6, 0x9e, 0x1a,
208
+            0x0b, 0xf5, 0x0e, 0x13, 0x30, 0x1e, 0x50, 0x26, 0xbd, 0x64, 0x08, 0x2c, 0x08, 0xdb,
209
+            0x0a, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
210
+            0xfa, 0x0d, 0xd4, 0x11, 0x91, 0x1b, 0xe6, 0xb2, 0x4e, 0x1e, 0x06, 0x49, 0x94, 0x11,
211
+            0xdd, 0x63, 0x62, 0x07, 0x59, 0x64, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
212
+            0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x46, 0x5c, 0xb9,
213
+            0xe1, 0xed, 0xea, 0xb9, 0x72, 0x9b, 0x82, 0xbd, 0xc5, 0xef, 0xed, 0x6d, 0x00, 0xf1,
214
+            0x24, 0xd3, 0x06, 0x68, 0x1f, 0x63, 0x54, 0xea, 0xde, 0x25, 0x56, 0x97, 0xd6, 0x05,
215
+            0xb3, 0x92, 0xbb, 0xc7, 0xc3, 0xa9, 0xf2, 0xef, 0xd2, 0x85, 0x2e, 0x18, 0x2e, 0x2d,
216
+            0x22, 0x1a, 0xf1, 0x48, 0x9d, 0x03, 0xe6, 0xc5, 0x18, 0x00, 0xdc, 0xa0, 0xda, 0x1a,
217
+            0x27, 0x87, 0x41, 0x16, 0xa0, 0xe8, 0xfa, 0x31, 0x28, 0xd9, 0x4b, 0xf6, 0xd0, 0x02,
218
+            0xec, 0x09, 0x75, 0xc6, 0xd0, 0x1e, 0x9f, 0x88, 0x7d, 0x5c, 0xb6, 0x45, 0x0d, 0x26,
219
+            0x3d, 0x09, 0x33, 0x20, 0x6e, 0x92, 0x2d, 0xe9, 0xfc, 0x40, 0x0a, 0x7d, 0xc2, 0x9a,
220
+            0xcb, 0xa4, 0x88, 0x8f, 0xef, 0xa4, 0xa3, 0x16, 0x6b, 0x29, 0x71, 0xfe, 0x5a, 0xf2,
221
+            0x7f, 0x37, 0xec, 0xa9, 0x9f, 0x79, 0x8e, 0x74, 0x28, 0x26, 0x89, 0xda, 0xf3,
222
+        ],
223
+    },
224
+    // APN-Win identity 000004.
225
+    SigningIdentity {
226
+        p: [
227
+            0xf3, 0xca, 0x6a, 0x26, 0xb4, 0x29, 0xd8, 0xb4, 0x1d, 0xc6, 0x91, 0x08, 0xe2, 0xfa,
228
+            0x6a, 0x1f, 0xd8, 0x55, 0xd6, 0x58, 0xcb, 0x1a, 0xac, 0xb7, 0xcf, 0x32, 0xdb, 0x91,
229
+            0xba, 0xa0, 0xbc, 0x44, 0x04, 0x39, 0xd8, 0x5c, 0xe9, 0xe0, 0x36, 0xce, 0x3e, 0xe3,
230
+            0x87, 0x4f, 0xd1, 0xbf, 0x83, 0xaa, 0x1d, 0xb8, 0x12, 0x18, 0x6e, 0x9a, 0x20, 0xe1,
231
+            0x95, 0x5f, 0x51, 0xbe, 0xed, 0xb8, 0xcc, 0x43,
232
+        ],
233
+        q: [
234
+            0xe9, 0x5a, 0x35, 0x40, 0x29, 0x81, 0x33, 0x5d, 0x59, 0x76, 0xc2, 0xfa, 0x9e, 0xdf,
235
+            0x20, 0x25, 0xcf, 0xac, 0xc4, 0xfa, 0x5f, 0x29, 0xdc, 0x2c, 0x56, 0xc4, 0x26, 0x95,
236
+            0x05, 0xb8, 0x54, 0x71, 0x93, 0xa7, 0xa6, 0x42, 0x5a, 0x66, 0x24, 0x90, 0xd8, 0xd7,
237
+            0x60, 0x59, 0xaf, 0x48, 0xce, 0xeb, 0x12, 0xe7, 0xad, 0x78, 0xed, 0x8d, 0xa4, 0xe5,
238
+            0xc9, 0x4d, 0xc4, 0x02, 0x01, 0x17, 0x44, 0x01,
239
+        ],
240
+        certificate: &[
241
+            0x30, 0x82, 0x02, 0xc5, 0x30, 0x82, 0x02, 0x2e, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
242
+            0x0d, 0x33, 0x33, 0xaf, 0x10, 0x10, 0x20, 0xaf, 0x00, 0x01, 0xaf, 0x00, 0x00, 0x04,
243
+            0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05,
244
+            0x00, 0x30, 0x7b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
245
+            0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41,
246
+            0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06,
247
+            0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65,
248
+            0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
249
+            0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x2f, 0x30, 0x2d, 0x06, 0x03, 0x55,
250
+            0x04, 0x03, 0x13, 0x26, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x46, 0x61, 0x69, 0x72,
251
+            0x50, 0x6c, 0x61, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
252
+            0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79,
253
+            0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x31, 0x30, 0x32, 0x30, 0x30, 0x30, 0x30, 0x32,
254
+            0x30, 0x33, 0x5a, 0x17, 0x0d, 0x31, 0x35, 0x31, 0x30, 0x31, 0x39, 0x30, 0x30, 0x30,
255
+            0x32, 0x30, 0x33, 0x5a, 0x30, 0x68, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
256
+            0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
257
+            0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x17,
258
+            0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0e, 0x41, 0x70, 0x70, 0x6c, 0x65,
259
+            0x20, 0x46, 0x61, 0x69, 0x72, 0x50, 0x6c, 0x61, 0x79, 0x31, 0x2b, 0x30, 0x29, 0x06,
260
+            0x03, 0x55, 0x04, 0x03, 0x13, 0x22, 0x41, 0x50, 0x4e, 0x2d, 0x57, 0x69, 0x6e, 0x2e,
261
+            0x33, 0x33, 0x33, 0x33, 0x41, 0x46, 0x31, 0x30, 0x31, 0x30, 0x32, 0x30, 0x41, 0x46,
262
+            0x30, 0x30, 0x30, 0x31, 0x41, 0x46, 0x30, 0x30, 0x30, 0x30, 0x30, 0x34, 0x30, 0x81,
263
+            0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
264
+            0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xde,
265
+            0x39, 0x22, 0x7c, 0x8d, 0xb0, 0x6e, 0xd5, 0xbb, 0xfb, 0xe3, 0xa2, 0xe8, 0x2a, 0x38,
266
+            0xe5, 0x96, 0x31, 0x44, 0xc7, 0xab, 0x34, 0xd7, 0xe0, 0x5a, 0xde, 0xfd, 0x29, 0x5c,
267
+            0xa3, 0x10, 0x38, 0xd8, 0x27, 0x37, 0x65, 0xaf, 0x35, 0x1b, 0x23, 0x20, 0x5c, 0x88,
268
+            0xa2, 0xb7, 0x12, 0xa6, 0xcd, 0x9b, 0x92, 0x29, 0x92, 0x14, 0xf0, 0xde, 0x58, 0xad,
269
+            0x80, 0xee, 0x01, 0xe1, 0xe4, 0xf7, 0x59, 0x09, 0x15, 0x33, 0x26, 0x5e, 0xbd, 0x3e,
270
+            0xe9, 0x2f, 0x83, 0xed, 0x5d, 0xa8, 0x4b, 0x8a, 0x48, 0x45, 0xeb, 0xd4, 0x81, 0xc4,
271
+            0xff, 0x2d, 0x5d, 0xcf, 0x57, 0x7c, 0x18, 0x48, 0x70, 0xf2, 0x0f, 0x64, 0xc2, 0x02,
272
+            0xe2, 0x09, 0x13, 0x1e, 0x54, 0x90, 0xd8, 0xda, 0x58, 0x64, 0xd7, 0xed, 0xa3, 0x69,
273
+            0xa7, 0x50, 0xcd, 0x6a, 0xa8, 0xe5, 0xd5, 0x61, 0x27, 0x01, 0xd0, 0xa0, 0xff, 0x98,
274
+            0x43, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x60, 0x30, 0x5e, 0x30, 0x0e, 0x06, 0x03,
275
+            0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x03, 0xb8, 0x30, 0x0c,
276
+            0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d,
277
+            0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x55, 0xf7, 0x3a, 0x58, 0x9e,
278
+            0x81, 0x1d, 0x7c, 0x17, 0x1c, 0x0b, 0xcf, 0x5c, 0x78, 0x0c, 0xa2, 0x49, 0x5e, 0xc9,
279
+            0x4b, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
280
+            0xfa, 0x0d, 0xd4, 0x11, 0x91, 0x1b, 0xe6, 0xb2, 0x4e, 0x1e, 0x06, 0x49, 0x94, 0x11,
281
+            0xdd, 0x63, 0x62, 0x07, 0x59, 0x64, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
282
+            0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x92, 0x7e, 0xf0,
283
+            0x9d, 0xc5, 0xbf, 0x3a, 0x1b, 0xd5, 0x6e, 0x32, 0x28, 0xa4, 0x0a, 0x78, 0x9e, 0x49,
284
+            0x26, 0x4c, 0xb6, 0x15, 0x6a, 0xf4, 0x03, 0xed, 0x19, 0x3b, 0x13, 0xa8, 0x78, 0x04,
285
+            0x6e, 0xea, 0x5d, 0xd6, 0x3c, 0xa7, 0xdf, 0x68, 0xbf, 0x26, 0x73, 0x19, 0xda, 0xe0,
286
+            0xfb, 0xb7, 0xa6, 0x2d, 0xbc, 0xf6, 0x88, 0x01, 0xa1, 0xa7, 0x2c, 0x24, 0x45, 0x10,
287
+            0xb3, 0xdc, 0x96, 0x99, 0xac, 0x65, 0x16, 0xb9, 0x85, 0x5c, 0xfe, 0x75, 0xfc, 0x6a,
288
+            0x3c, 0x99, 0x83, 0x18, 0x06, 0x22, 0x72, 0xa1, 0xbd, 0xdd, 0xbc, 0xd8, 0x24, 0x64,
289
+            0x48, 0x7c, 0x52, 0xa9, 0x4c, 0xae, 0xc8, 0x18, 0x1e, 0xd0, 0x2c, 0x8b, 0xfb, 0xe0,
290
+            0x01, 0xab, 0xcc, 0x4d, 0x9f, 0x80, 0x10, 0xcb, 0x46, 0xea, 0xa9, 0xab, 0x0e, 0xfe,
291
+            0x75, 0x23, 0x61, 0xb2, 0x72, 0x04, 0x52, 0x7c, 0x40, 0x27, 0x34, 0x05, 0x1a,
292
+        ],
293
+    },
294
+    // APN-Win identity 000005.
295
+    SigningIdentity {
296
+        p: [
297
+            0xf5, 0x5d, 0x32, 0x17, 0xc3, 0xc2, 0x52, 0x4b, 0x88, 0x00, 0xb4, 0xe7, 0x0e, 0xa7,
298
+            0x96, 0xf3, 0x88, 0xeb, 0x59, 0xe3, 0x62, 0xb8, 0xb9, 0x8d, 0xf2, 0x6b, 0x9e, 0xc7,
299
+            0x39, 0x78, 0x84, 0xa4, 0x3f, 0x08, 0x25, 0xc7, 0x6d, 0x96, 0xd5, 0x3f, 0x23, 0x71,
300
+            0x86, 0x19, 0x0c, 0x7f, 0xc6, 0x5a, 0x9f, 0xdb, 0x7b, 0xb3, 0x6e, 0xd5, 0x6f, 0xde,
301
+            0xcf, 0xb5, 0x33, 0xac, 0x0c, 0xfa, 0xa1, 0xff,
302
+        ],
303
+        q: [
304
+            0xdc, 0x8d, 0xae, 0x74, 0x7e, 0x51, 0xf0, 0x39, 0xc5, 0x12, 0xd1, 0x4d, 0x45, 0x41,
305
+            0xf4, 0x71, 0x85, 0xf4, 0x00, 0xc5, 0xff, 0xda, 0x6e, 0x98, 0xbb, 0x6c, 0x86, 0x8c,
306
+            0x2c, 0xd6, 0x30, 0xb3, 0x8d, 0x34, 0xd3, 0x43, 0x50, 0xfc, 0x0c, 0x85, 0x56, 0xc5,
307
+            0x01, 0xa6, 0x86, 0x98, 0x05, 0x49, 0xc7, 0xb9, 0x7d, 0x8b, 0x61, 0xd9, 0xe1, 0x8a,
308
+            0x22, 0xa2, 0xa7, 0x8d, 0x18, 0x21, 0x55, 0xab,
309
+        ],
310
+        certificate: &[
311
+            0x30, 0x82, 0x02, 0xc5, 0x30, 0x82, 0x02, 0x2e, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
312
+            0x0d, 0x33, 0x33, 0xaf, 0x10, 0x10, 0x20, 0xaf, 0x00, 0x01, 0xaf, 0x00, 0x00, 0x05,
313
+            0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05,
314
+            0x00, 0x30, 0x7b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
315
+            0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41,
316
+            0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06,
317
+            0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65,
318
+            0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
319
+            0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x2f, 0x30, 0x2d, 0x06, 0x03, 0x55,
320
+            0x04, 0x03, 0x13, 0x26, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x46, 0x61, 0x69, 0x72,
321
+            0x50, 0x6c, 0x61, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
322
+            0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79,
323
+            0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x31, 0x30, 0x32, 0x30, 0x30, 0x30, 0x30, 0x32,
324
+            0x30, 0x33, 0x5a, 0x17, 0x0d, 0x31, 0x35, 0x31, 0x30, 0x31, 0x39, 0x30, 0x30, 0x30,
325
+            0x32, 0x30, 0x33, 0x5a, 0x30, 0x68, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
326
+            0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
327
+            0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x17,
328
+            0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0e, 0x41, 0x70, 0x70, 0x6c, 0x65,
329
+            0x20, 0x46, 0x61, 0x69, 0x72, 0x50, 0x6c, 0x61, 0x79, 0x31, 0x2b, 0x30, 0x29, 0x06,
330
+            0x03, 0x55, 0x04, 0x03, 0x13, 0x22, 0x41, 0x50, 0x4e, 0x2d, 0x57, 0x69, 0x6e, 0x2e,
331
+            0x33, 0x33, 0x33, 0x33, 0x41, 0x46, 0x31, 0x30, 0x31, 0x30, 0x32, 0x30, 0x41, 0x46,
332
+            0x30, 0x30, 0x30, 0x31, 0x41, 0x46, 0x30, 0x30, 0x30, 0x30, 0x30, 0x35, 0x30, 0x81,
333
+            0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
334
+            0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xd3,
335
+            0x63, 0xe2, 0x96, 0x02, 0xab, 0x11, 0xf6, 0x4d, 0xee, 0xe9, 0x07, 0x3e, 0x02, 0xba,
336
+            0xae, 0x14, 0x15, 0x42, 0xfe, 0xad, 0xdc, 0xd8, 0x76, 0x34, 0xf0, 0x7a, 0x0a, 0xfa,
337
+            0xf0, 0x1e, 0x54, 0x19, 0xb5, 0xdd, 0x73, 0xb0, 0xdc, 0xc7, 0xd4, 0xcb, 0xf5, 0xa1,
338
+            0x2c, 0x93, 0x5e, 0x32, 0x6a, 0xbd, 0x66, 0x88, 0x20, 0xb2, 0x98, 0x39, 0xd0, 0xed,
339
+            0x37, 0x96, 0x31, 0x4a, 0xba, 0xe3, 0xe8, 0x25, 0x66, 0x5c, 0x65, 0x36, 0xe8, 0xbd,
340
+            0x81, 0x23, 0xc1, 0x9d, 0xef, 0x78, 0x93, 0x7d, 0x19, 0xc0, 0x93, 0x2a, 0x8f, 0x82,
341
+            0xed, 0x00, 0x74, 0x10, 0x6e, 0xc8, 0xf3, 0x95, 0x4d, 0xff, 0x9b, 0xb6, 0x59, 0x46,
342
+            0x58, 0x3b, 0xe0, 0xa1, 0xee, 0x63, 0x3c, 0xe4, 0xb3, 0x5c, 0xc1, 0xbd, 0xea, 0x05,
343
+            0xa2, 0x7b, 0xd8, 0x95, 0xa8, 0x1c, 0xce, 0xb9, 0xad, 0x62, 0x2d, 0xad, 0x12, 0xe0,
344
+            0x55, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x60, 0x30, 0x5e, 0x30, 0x0e, 0x06, 0x03,
345
+            0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x03, 0xb8, 0x30, 0x0c,
346
+            0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d,
347
+            0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x31, 0xb5, 0x80, 0xdd, 0x93,
348
+            0x24, 0x80, 0x5f, 0x30, 0x80, 0x6c, 0x40, 0x44, 0xcd, 0x85, 0x85, 0x6e, 0x87, 0x48,
349
+            0xf7, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
350
+            0xfa, 0x0d, 0xd4, 0x11, 0x91, 0x1b, 0xe6, 0xb2, 0x4e, 0x1e, 0x06, 0x49, 0x94, 0x11,
351
+            0xdd, 0x63, 0x62, 0x07, 0x59, 0x64, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
352
+            0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x96, 0xd7, 0xdf,
353
+            0x77, 0x6e, 0x25, 0x6a, 0x26, 0xbe, 0xe9, 0x4b, 0xb0, 0xc1, 0x88, 0xc6, 0x76, 0x39,
354
+            0x84, 0x15, 0x17, 0xbf, 0x50, 0x74, 0x95, 0x02, 0xcf, 0x02, 0xc4, 0x3c, 0x79, 0xde,
355
+            0xec, 0x36, 0x2f, 0x1d, 0x31, 0x4c, 0xcd, 0xaf, 0x69, 0x73, 0x32, 0xac, 0x1e, 0xa3,
356
+            0xcd, 0x08, 0x1a, 0xed, 0x58, 0xc9, 0xfc, 0xb7, 0x0e, 0x5d, 0x56, 0x6f, 0xef, 0xcd,
357
+            0x4e, 0xf7, 0xf9, 0x71, 0x46, 0x4b, 0x23, 0x09, 0x61, 0x73, 0x3c, 0xd3, 0x93, 0xe2,
358
+            0xb7, 0x40, 0xfd, 0x03, 0xf9, 0xb0, 0x2d, 0x05, 0x55, 0xac, 0xfa, 0x73, 0x99, 0x4d,
359
+            0xc1, 0xca, 0x93, 0x67, 0xf3, 0xa7, 0x3e, 0x76, 0x06, 0x45, 0x7c, 0x97, 0x57, 0xc2,
360
+            0xd6, 0x40, 0x48, 0x28, 0xe6, 0xfb, 0x6a, 0xfe, 0x4f, 0x07, 0x6c, 0xf5, 0x68, 0xcf,
361
+            0xad, 0x12, 0x88, 0xc4, 0x9e, 0xb8, 0x45, 0x70, 0x5c, 0xe4, 0x57, 0x2a, 0x28,
362
+        ],
363
+    },
364
+    // APN-Win identity 000006.
365
+    SigningIdentity {
366
+        p: [
367
+            0xe3, 0x7b, 0xc2, 0x31, 0x22, 0x8a, 0x5c, 0x8f, 0x03, 0xcb, 0x6c, 0xde, 0x92, 0x6f,
368
+            0xb0, 0x88, 0x47, 0x43, 0x7b, 0xac, 0x72, 0xd9, 0x94, 0x31, 0x2d, 0xd9, 0xa6, 0xdf,
369
+            0xf1, 0x83, 0x41, 0xac, 0x3a, 0x21, 0xe9, 0x52, 0x19, 0xdb, 0x44, 0xf4, 0xe4, 0x4b,
370
+            0xd0, 0x18, 0x8e, 0xa6, 0x30, 0xa5, 0xa2, 0x3c, 0xb9, 0xa7, 0x7d, 0x78, 0x07, 0x0d,
371
+            0x7b, 0x4c, 0xe5, 0xdb, 0x52, 0x4e, 0x7d, 0x95,
372
+        ],
373
+        q: [
374
+            0xc2, 0x06, 0xe8, 0x58, 0x13, 0x8f, 0xcb, 0xdc, 0x92, 0x56, 0xb6, 0x3e, 0x4e, 0x03,
375
+            0x18, 0xcb, 0x35, 0x73, 0x4f, 0x78, 0x73, 0x09, 0xc5, 0xee, 0x00, 0x83, 0x52, 0x28,
376
+            0xd4, 0xb3, 0x6b, 0xb4, 0xfb, 0xd1, 0x39, 0x2f, 0x4d, 0x7b, 0xad, 0x76, 0x42, 0x83,
377
+            0x3f, 0x24, 0x4d, 0x07, 0x45, 0xe9, 0x10, 0x77, 0xad, 0xac, 0x4a, 0xd8, 0x6d, 0x1e,
378
+            0xab, 0x1a, 0x9e, 0xa2, 0x21, 0x93, 0x62, 0x33,
379
+        ],
380
+        certificate: &[
381
+            0x30, 0x82, 0x02, 0xc5, 0x30, 0x82, 0x02, 0x2e, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
382
+            0x0d, 0x33, 0x33, 0xaf, 0x10, 0x10, 0x20, 0xaf, 0x00, 0x01, 0xaf, 0x00, 0x00, 0x06,
383
+            0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05,
384
+            0x00, 0x30, 0x7b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
385
+            0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41,
386
+            0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06,
387
+            0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65,
388
+            0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
389
+            0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x2f, 0x30, 0x2d, 0x06, 0x03, 0x55,
390
+            0x04, 0x03, 0x13, 0x26, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x46, 0x61, 0x69, 0x72,
391
+            0x50, 0x6c, 0x61, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
392
+            0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79,
393
+            0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x31, 0x30, 0x32, 0x30, 0x30, 0x30, 0x30, 0x32,
394
+            0x30, 0x34, 0x5a, 0x17, 0x0d, 0x31, 0x35, 0x31, 0x30, 0x31, 0x39, 0x30, 0x30, 0x30,
395
+            0x32, 0x30, 0x34, 0x5a, 0x30, 0x68, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
396
+            0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
397
+            0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x17,
398
+            0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0e, 0x41, 0x70, 0x70, 0x6c, 0x65,
399
+            0x20, 0x46, 0x61, 0x69, 0x72, 0x50, 0x6c, 0x61, 0x79, 0x31, 0x2b, 0x30, 0x29, 0x06,
400
+            0x03, 0x55, 0x04, 0x03, 0x13, 0x22, 0x41, 0x50, 0x4e, 0x2d, 0x57, 0x69, 0x6e, 0x2e,
401
+            0x33, 0x33, 0x33, 0x33, 0x41, 0x46, 0x31, 0x30, 0x31, 0x30, 0x32, 0x30, 0x41, 0x46,
402
+            0x30, 0x30, 0x30, 0x31, 0x41, 0x46, 0x30, 0x30, 0x30, 0x30, 0x30, 0x36, 0x30, 0x81,
403
+            0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
404
+            0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xac,
405
+            0x69, 0xec, 0x86, 0x35, 0x3c, 0xe8, 0x46, 0x12, 0x0f, 0xb6, 0xe9, 0x33, 0xce, 0x4d,
406
+            0x9c, 0xae, 0x60, 0xc2, 0xd1, 0x12, 0x4b, 0xe9, 0x43, 0xce, 0x44, 0x9d, 0x2f, 0x85,
407
+            0x58, 0xdb, 0x4d, 0x9f, 0xa0, 0x7f, 0x94, 0x59, 0x4b, 0x63, 0x8f, 0xb5, 0x62, 0xe6,
408
+            0x4c, 0x24, 0x19, 0x03, 0x2d, 0xdc, 0x81, 0x4a, 0x40, 0x88, 0xd8, 0x59, 0xeb, 0xe1,
409
+            0xef, 0x4b, 0xc3, 0x98, 0xc0, 0xf4, 0x7c, 0xea, 0xd8, 0x2b, 0x67, 0x62, 0xd1, 0x30,
410
+            0x63, 0xe9, 0xc7, 0xf5, 0xe8, 0x70, 0xa9, 0x20, 0xaa, 0x5e, 0x65, 0x13, 0x84, 0xd0,
411
+            0x27, 0xcf, 0xf3, 0xe3, 0x21, 0x0a, 0x76, 0x36, 0xde, 0xc4, 0x69, 0x63, 0x33, 0x21,
412
+            0x58, 0x9f, 0x2e, 0xe2, 0x80, 0xcf, 0xa8, 0x59, 0xda, 0x8a, 0x1f, 0xf6, 0x90, 0x86,
413
+            0x24, 0xd0, 0x97, 0x28, 0x6a, 0x0b, 0x94, 0x12, 0x2b, 0x8f, 0xbf, 0xc3, 0x45, 0x0e,
414
+            0xaf, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x60, 0x30, 0x5e, 0x30, 0x0e, 0x06, 0x03,
415
+            0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x03, 0xb8, 0x30, 0x0c,
416
+            0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d,
417
+            0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x0f, 0x4d, 0x5f, 0x83, 0x52,
418
+            0x56, 0x19, 0xa0, 0x76, 0x8f, 0x4b, 0xee, 0xf0, 0xed, 0xd8, 0x02, 0x0d, 0x3a, 0x00,
419
+            0xdc, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
420
+            0xfa, 0x0d, 0xd4, 0x11, 0x91, 0x1b, 0xe6, 0xb2, 0x4e, 0x1e, 0x06, 0x49, 0x94, 0x11,
421
+            0xdd, 0x63, 0x62, 0x07, 0x59, 0x64, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
422
+            0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x2b, 0x82, 0x74,
423
+            0x72, 0x5a, 0x54, 0x4c, 0x54, 0x54, 0x37, 0x6e, 0xd8, 0xcf, 0xa8, 0x3e, 0x1f, 0x8d,
424
+            0xd0, 0x26, 0xe5, 0x47, 0xf4, 0x1a, 0xc9, 0x35, 0x7a, 0xce, 0xec, 0xca, 0x38, 0x3b,
425
+            0x94, 0x54, 0xd8, 0xae, 0x7c, 0xf8, 0x45, 0x5f, 0xfa, 0xd4, 0xbd, 0x4f, 0x1a, 0x22,
426
+            0x27, 0xe7, 0x69, 0xf5, 0xaa, 0xed, 0xcf, 0x3b, 0x0b, 0xc2, 0x74, 0x1e, 0xa5, 0x7d,
427
+            0x75, 0x3b, 0x3f, 0x94, 0xe7, 0x19, 0x38, 0x42, 0x24, 0xbc, 0xb1, 0x36, 0x52, 0x35,
428
+            0x3d, 0xac, 0x49, 0xa0, 0x25, 0xe0, 0x22, 0xc1, 0xea, 0x55, 0x0d, 0xba, 0x43, 0xd3,
429
+            0x5f, 0x07, 0xdc, 0x5f, 0x59, 0x1b, 0x48, 0x13, 0x4f, 0xd7, 0x4e, 0x6d, 0x07, 0x08,
430
+            0xc1, 0xb4, 0x00, 0x92, 0x84, 0xcf, 0xa0, 0xbd, 0xdf, 0x33, 0xaa, 0x3f, 0xfd, 0x8b,
431
+            0x99, 0x87, 0x8d, 0x46, 0x45, 0xa9, 0x3d, 0x0a, 0x65, 0x9d, 0xd2, 0x15, 0xb0,
432
+        ],
433
+    },
434
+    // APN-Win identity 000007.
435
+    SigningIdentity {
436
+        p: [
437
+            0xf0, 0xad, 0x75, 0x6a, 0xdb, 0x42, 0x8d, 0x70, 0x3c, 0xa4, 0xba, 0xa5, 0x87, 0xa9,
438
+            0x1e, 0xc3, 0xd7, 0x6d, 0xe5, 0x46, 0x97, 0xa6, 0x8a, 0x7a, 0x09, 0x44, 0xdc, 0x33,
439
+            0x71, 0xb6, 0xb7, 0x9f, 0x2d, 0x44, 0xfa, 0x64, 0xcf, 0xd0, 0xa2, 0x5a, 0x8d, 0x2d,
440
+            0x67, 0xed, 0x62, 0x07, 0x7f, 0xfa, 0x23, 0x4c, 0xa2, 0x75, 0x90, 0xce, 0xc0, 0xf5,
441
+            0xfc, 0x79, 0x3b, 0x30, 0x96, 0x3b, 0x57, 0xe5,
442
+        ],
443
+        q: [
444
+            0xef, 0x4b, 0x6c, 0x26, 0x07, 0xf1, 0x3f, 0x3a, 0xf7, 0xbb, 0x7b, 0x9c, 0xff, 0x16,
445
+            0xeb, 0xb3, 0x72, 0xf8, 0x33, 0x95, 0xb0, 0x94, 0xed, 0xf2, 0xdc, 0x6f, 0x24, 0x1c,
446
+            0x87, 0xec, 0x6a, 0x26, 0x16, 0xb0, 0xf8, 0x80, 0x4c, 0xbe, 0xa9, 0xfd, 0x7c, 0x2a,
447
+            0x88, 0x6d, 0xf4, 0x1f, 0x55, 0xac, 0x98, 0x2a, 0xaf, 0x6e, 0x1f, 0x93, 0xd9, 0x46,
448
+            0xf7, 0xb9, 0x5e, 0xef, 0x7b, 0xc5, 0x5c, 0x03,
449
+        ],
450
+        certificate: &[
451
+            0x30, 0x82, 0x02, 0xc5, 0x30, 0x82, 0x02, 0x2e, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
452
+            0x0d, 0x33, 0x33, 0xaf, 0x10, 0x10, 0x20, 0xaf, 0x00, 0x01, 0xaf, 0x00, 0x00, 0x07,
453
+            0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05,
454
+            0x00, 0x30, 0x7b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
455
+            0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41,
456
+            0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06,
457
+            0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65,
458
+            0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
459
+            0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x2f, 0x30, 0x2d, 0x06, 0x03, 0x55,
460
+            0x04, 0x03, 0x13, 0x26, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x46, 0x61, 0x69, 0x72,
461
+            0x50, 0x6c, 0x61, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
462
+            0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79,
463
+            0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x31, 0x30, 0x32, 0x30, 0x30, 0x30, 0x30, 0x32,
464
+            0x30, 0x34, 0x5a, 0x17, 0x0d, 0x31, 0x35, 0x31, 0x30, 0x31, 0x39, 0x30, 0x30, 0x30,
465
+            0x32, 0x30, 0x34, 0x5a, 0x30, 0x68, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
466
+            0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
467
+            0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x17,
468
+            0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0e, 0x41, 0x70, 0x70, 0x6c, 0x65,
469
+            0x20, 0x46, 0x61, 0x69, 0x72, 0x50, 0x6c, 0x61, 0x79, 0x31, 0x2b, 0x30, 0x29, 0x06,
470
+            0x03, 0x55, 0x04, 0x03, 0x13, 0x22, 0x41, 0x50, 0x4e, 0x2d, 0x57, 0x69, 0x6e, 0x2e,
471
+            0x33, 0x33, 0x33, 0x33, 0x41, 0x46, 0x31, 0x30, 0x31, 0x30, 0x32, 0x30, 0x41, 0x46,
472
+            0x30, 0x30, 0x30, 0x31, 0x41, 0x46, 0x30, 0x30, 0x30, 0x30, 0x30, 0x37, 0x30, 0x81,
473
+            0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
474
+            0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xe0,
475
+            0xf8, 0xd9, 0x1d, 0x17, 0xc1, 0x6d, 0xdb, 0x6d, 0xbc, 0xa7, 0xa7, 0xcd, 0x17, 0x07,
476
+            0x9b, 0x83, 0x21, 0x86, 0x81, 0x37, 0x40, 0x68, 0x2c, 0xec, 0x2d, 0x45, 0x55, 0xe9,
477
+            0x84, 0xcc, 0x40, 0x86, 0xd5, 0x2b, 0x6a, 0x1f, 0x1f, 0xbc, 0x3c, 0x3e, 0xb3, 0x55,
478
+            0xdd, 0x0a, 0x49, 0x60, 0x80, 0xb5, 0x12, 0x94, 0xfc, 0xc2, 0xfc, 0x78, 0xb8, 0xaf,
479
+            0xba, 0x7f, 0xc1, 0x75, 0x65, 0x67, 0xd0, 0x9a, 0x31, 0x51, 0xe1, 0xd4, 0xb4, 0x16,
480
+            0xde, 0xed, 0xe9, 0x80, 0x52, 0xb6, 0xd0, 0x33, 0x44, 0xed, 0x2b, 0x0d, 0x08, 0xa5,
481
+            0x08, 0xe7, 0xa1, 0x5a, 0xe1, 0x10, 0x38, 0xce, 0x30, 0x0a, 0x74, 0xd7, 0x57, 0x56,
482
+            0x9d, 0x33, 0x85, 0x52, 0x7f, 0xb3, 0xe5, 0xd0, 0x2e, 0x58, 0xd5, 0xe5, 0x93, 0x87,
483
+            0x21, 0xf3, 0x0e, 0x22, 0x92, 0x44, 0x2c, 0xee, 0x6d, 0x6b, 0x3f, 0xc0, 0x81, 0x53,
484
+            0xaf, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x60, 0x30, 0x5e, 0x30, 0x0e, 0x06, 0x03,
485
+            0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x03, 0xb8, 0x30, 0x0c,
486
+            0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d,
487
+            0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xad, 0x58, 0x03, 0x97, 0xe3,
488
+            0xf9, 0x03, 0x0c, 0xd5, 0x01, 0x0b, 0x68, 0x0a, 0xa5, 0xb7, 0xec, 0x6c, 0x27, 0x71,
489
+            0x61, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
490
+            0xfa, 0x0d, 0xd4, 0x11, 0x91, 0x1b, 0xe6, 0xb2, 0x4e, 0x1e, 0x06, 0x49, 0x94, 0x11,
491
+            0xdd, 0x63, 0x62, 0x07, 0x59, 0x64, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
492
+            0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x66, 0xc5, 0x8e,
493
+            0xa8, 0x43, 0xd2, 0x34, 0x6e, 0x85, 0x03, 0xd3, 0xc5, 0xef, 0x0a, 0x31, 0xda, 0x1e,
494
+            0x84, 0xde, 0xd9, 0x40, 0x79, 0xc9, 0xdd, 0x5a, 0x24, 0xf5, 0xcc, 0xca, 0x47, 0x65,
495
+            0x69, 0xe3, 0x6f, 0x0c, 0x4e, 0x58, 0x95, 0x6f, 0x86, 0x18, 0x4c, 0x94, 0xe9, 0xc5,
496
+            0x49, 0xbd, 0x47, 0xac, 0xfe, 0xb1, 0xf4, 0x68, 0xbc, 0x1e, 0xe7, 0x8a, 0x66, 0x60,
497
+            0xcd, 0x39, 0x20, 0x1c, 0x06, 0x56, 0x19, 0xc7, 0x4c, 0xe2, 0x0e, 0x0e, 0x15, 0x86,
498
+            0xe8, 0xf3, 0xa3, 0xb5, 0x4a, 0xc4, 0x44, 0x73, 0x37, 0x10, 0xa8, 0xa9, 0x7e, 0x18,
499
+            0x72, 0x9c, 0xef, 0x77, 0xed, 0x1b, 0x21, 0x6a, 0xcd, 0xd9, 0x9d, 0xee, 0x17, 0xf6,
500
+            0x56, 0x31, 0x18, 0xf5, 0xf0, 0x35, 0xbc, 0x14, 0x33, 0x76, 0x91, 0xd8, 0xa6, 0x7c,
501
+            0x86, 0x7f, 0x80, 0x69, 0xe2, 0xb1, 0xaa, 0x30, 0xec, 0xf4, 0xe3, 0xd5, 0x1c,
502
+        ],
503
+    },
504
+    // APN-Win identity 000008.
505
+    SigningIdentity {
506
+        p: [
507
+            0xcb, 0x6a, 0xa4, 0xbb, 0xe3, 0x96, 0x51, 0x43, 0x94, 0x2e, 0x5e, 0x0f, 0x33, 0x0b,
508
+            0x10, 0xcc, 0xf0, 0xfe, 0xa8, 0x83, 0x19, 0x3f, 0xdd, 0xed, 0x1f, 0x11, 0xe4, 0xcc,
509
+            0x72, 0xd6, 0xf9, 0x9e, 0x64, 0x03, 0x71, 0x2d, 0xa8, 0xa9, 0xcd, 0xfe, 0x02, 0xf0,
510
+            0x72, 0xf9, 0xfb, 0xd7, 0x13, 0xce, 0x69, 0x23, 0x84, 0x03, 0xd2, 0xc3, 0x30, 0xd8,
511
+            0x2a, 0xb3, 0x63, 0xb2, 0xfd, 0x12, 0x6a, 0x2f,
512
+        ],
513
+        q: [
514
+            0xc4, 0x4e, 0xb8, 0xc1, 0x5c, 0x87, 0xd0, 0x58, 0x95, 0x78, 0x3d, 0x21, 0xf3, 0xef,
515
+            0x05, 0x52, 0x93, 0x41, 0xe3, 0x6a, 0x10, 0x84, 0x5f, 0xbb, 0x7e, 0x26, 0x7f, 0x64,
516
+            0xe7, 0x70, 0x6f, 0x12, 0x41, 0x42, 0xc3, 0x5f, 0xf4, 0x60, 0xfc, 0x48, 0x91, 0x92,
517
+            0x45, 0x63, 0x0e, 0xa1, 0x80, 0x68, 0x0b, 0x6a, 0x0b, 0x0d, 0xae, 0xed, 0x29, 0x0f,
518
+            0xfe, 0x5f, 0xc6, 0xff, 0x23, 0x41, 0x3e, 0x11,
519
+        ],
520
+        certificate: &[
521
+            0x30, 0x82, 0x02, 0xc5, 0x30, 0x82, 0x02, 0x2e, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
522
+            0x0d, 0x33, 0x33, 0xaf, 0x10, 0x10, 0x20, 0xaf, 0x00, 0x01, 0xaf, 0x00, 0x00, 0x08,
523
+            0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05,
524
+            0x00, 0x30, 0x7b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
525
+            0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41,
526
+            0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06,
527
+            0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65,
528
+            0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
529
+            0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x2f, 0x30, 0x2d, 0x06, 0x03, 0x55,
530
+            0x04, 0x03, 0x13, 0x26, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x46, 0x61, 0x69, 0x72,
531
+            0x50, 0x6c, 0x61, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
532
+            0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79,
533
+            0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x31, 0x30, 0x32, 0x30, 0x30, 0x30, 0x30, 0x32,
534
+            0x30, 0x35, 0x5a, 0x17, 0x0d, 0x31, 0x35, 0x31, 0x30, 0x31, 0x39, 0x30, 0x30, 0x30,
535
+            0x32, 0x30, 0x35, 0x5a, 0x30, 0x68, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
536
+            0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
537
+            0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x17,
538
+            0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0e, 0x41, 0x70, 0x70, 0x6c, 0x65,
539
+            0x20, 0x46, 0x61, 0x69, 0x72, 0x50, 0x6c, 0x61, 0x79, 0x31, 0x2b, 0x30, 0x29, 0x06,
540
+            0x03, 0x55, 0x04, 0x03, 0x13, 0x22, 0x41, 0x50, 0x4e, 0x2d, 0x57, 0x69, 0x6e, 0x2e,
541
+            0x33, 0x33, 0x33, 0x33, 0x41, 0x46, 0x31, 0x30, 0x31, 0x30, 0x32, 0x30, 0x41, 0x46,
542
+            0x30, 0x30, 0x30, 0x31, 0x41, 0x46, 0x30, 0x30, 0x30, 0x30, 0x30, 0x38, 0x30, 0x81,
543
+            0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
544
+            0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0x9b,
545
+            0xfc, 0x33, 0x6c, 0x56, 0xd1, 0xe9, 0x3c, 0x8c, 0xeb, 0x6c, 0x03, 0xcf, 0x39, 0xd6,
546
+            0xa1, 0x8e, 0x96, 0x27, 0xdf, 0xfa, 0xf8, 0x56, 0x73, 0x05, 0x5f, 0x16, 0xc3, 0x6a,
547
+            0xc0, 0x3b, 0x1a, 0x27, 0x10, 0x79, 0x5c, 0x5a, 0xbb, 0x4a, 0x14, 0xdf, 0xa9, 0x42,
548
+            0x36, 0x6f, 0x95, 0x2e, 0xcc, 0x15, 0xf9, 0x19, 0x16, 0xc6, 0x85, 0xb8, 0x53, 0x7c,
549
+            0xbc, 0x47, 0xe4, 0x54, 0xda, 0x8c, 0x94, 0xae, 0x89, 0x37, 0xf4, 0xfd, 0x3c, 0x97,
550
+            0x3f, 0x9f, 0x9a, 0xf6, 0x28, 0x6c, 0xda, 0x7e, 0xb7, 0x8f, 0x29, 0xeb, 0xf5, 0x01,
551
+            0x18, 0x1d, 0x15, 0x00, 0x33, 0xa4, 0x62, 0xe7, 0xb8, 0xb3, 0x86, 0x58, 0x09, 0xbc,
552
+            0xf3, 0x42, 0x94, 0x0b, 0x0c, 0xf6, 0x3c, 0x58, 0x11, 0x03, 0xcc, 0x1a, 0x8a, 0xf4,
553
+            0x0f, 0x4c, 0x00, 0x1e, 0x6d, 0xa4, 0xd7, 0x6e, 0x03, 0xdd, 0x2f, 0xa6, 0xdf, 0x6f,
554
+            0x1f, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x60, 0x30, 0x5e, 0x30, 0x0e, 0x06, 0x03,
555
+            0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x03, 0xb8, 0x30, 0x0c,
556
+            0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d,
557
+            0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xf7, 0x93, 0xef, 0x48, 0x8c,
558
+            0xb6, 0x71, 0xee, 0x83, 0x05, 0x1e, 0x1e, 0x76, 0xb0, 0xdc, 0xb0, 0xa7, 0xcb, 0x4c,
559
+            0x8c, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
560
+            0xfa, 0x0d, 0xd4, 0x11, 0x91, 0x1b, 0xe6, 0xb2, 0x4e, 0x1e, 0x06, 0x49, 0x94, 0x11,
561
+            0xdd, 0x63, 0x62, 0x07, 0x59, 0x64, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
562
+            0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x50, 0xdb, 0xf6,
563
+            0xef, 0xad, 0xb5, 0x9e, 0x56, 0x4b, 0xf1, 0x69, 0x3a, 0xc2, 0x49, 0x2a, 0x7b, 0x3d,
564
+            0x47, 0x30, 0x67, 0xae, 0x0f, 0x3f, 0xdf, 0xc1, 0x36, 0x9b, 0x0f, 0x42, 0x02, 0x56,
565
+            0x11, 0x22, 0xe4, 0x8c, 0x60, 0xe6, 0x12, 0x1d, 0x1c, 0x8a, 0x19, 0xb7, 0x52, 0x3f,
566
+            0x6a, 0xae, 0xf4, 0xed, 0x96, 0x6e, 0xa0, 0x5f, 0x67, 0x50, 0xf1, 0xdf, 0x02, 0xe5,
567
+            0xe5, 0x46, 0x92, 0xa2, 0xce, 0x11, 0x90, 0x34, 0xd6, 0x2f, 0x81, 0x3a, 0xc8, 0x04,
568
+            0x9a, 0x60, 0x91, 0x0d, 0x7f, 0xe6, 0xf4, 0x01, 0xc6, 0x0b, 0x88, 0x39, 0x95, 0x17,
569
+            0xeb, 0x3c, 0x1f, 0xb2, 0x8a, 0x07, 0x4c, 0xe3, 0xd1, 0x5b, 0xc0, 0x24, 0x10, 0xf3,
570
+            0x56, 0x94, 0xe9, 0xc3, 0xb3, 0x3c, 0x7f, 0x3d, 0x9b, 0x0e, 0x43, 0x1d, 0x9e, 0x8c,
571
+            0xb0, 0x65, 0x3c, 0x22, 0xb6, 0x28, 0x56, 0x79, 0xa3, 0xef, 0xb9, 0x5b, 0x06,
572
+        ],
573
+    },
574
+    // APN-Win identity 000009.
575
+    SigningIdentity {
576
+        p: [
577
+            0xe6, 0x4f, 0x46, 0x42, 0xfe, 0xc8, 0x2c, 0x82, 0xf0, 0xe2, 0xee, 0x28, 0xb0, 0xdd,
578
+            0x4b, 0x5a, 0xe7, 0xc9, 0x6e, 0x02, 0xaa, 0xba, 0x3a, 0xe9, 0xe0, 0xc4, 0xcb, 0xb0,
579
+            0xc6, 0xd8, 0x3f, 0x88, 0x1c, 0x28, 0x89, 0x22, 0xca, 0x61, 0x62, 0x64, 0xbf, 0x3b,
580
+            0x49, 0xd8, 0xad, 0x8d, 0x99, 0xf1, 0xca, 0x75, 0xb4, 0xd9, 0x12, 0x18, 0x9a, 0x3c,
581
+            0xab, 0xc8, 0x97, 0x77, 0x85, 0x36, 0xe2, 0xe3,
582
+        ],
583
+        q: [
584
+            0xc3, 0x59, 0x95, 0x2b, 0x7f, 0xeb, 0x24, 0x78, 0xda, 0xd4, 0x41, 0x79, 0x90, 0xb3,
585
+            0x62, 0xd4, 0x33, 0xd1, 0x6d, 0x11, 0x59, 0x3e, 0x6a, 0x8b, 0x90, 0x73, 0x8a, 0x51,
586
+            0xc8, 0x15, 0xe6, 0x93, 0x93, 0x98, 0xf7, 0xc1, 0xbc, 0x17, 0x48, 0x53, 0x88, 0x88,
587
+            0xe5, 0x93, 0xeb, 0x6e, 0x47, 0xb5, 0x97, 0x83, 0x4e, 0x50, 0x47, 0x21, 0x76, 0x37,
588
+            0x32, 0xdc, 0x3d, 0xc4, 0x79, 0x8e, 0xbc, 0xd9,
589
+        ],
590
+        certificate: &[
591
+            0x30, 0x82, 0x02, 0xc5, 0x30, 0x82, 0x02, 0x2e, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
592
+            0x0d, 0x33, 0x33, 0xaf, 0x10, 0x10, 0x20, 0xaf, 0x00, 0x01, 0xaf, 0x00, 0x00, 0x09,
593
+            0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05,
594
+            0x00, 0x30, 0x7b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
595
+            0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41,
596
+            0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06,
597
+            0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65,
598
+            0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
599
+            0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x2f, 0x30, 0x2d, 0x06, 0x03, 0x55,
600
+            0x04, 0x03, 0x13, 0x26, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x46, 0x61, 0x69, 0x72,
601
+            0x50, 0x6c, 0x61, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
602
+            0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79,
603
+            0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x31, 0x30, 0x32, 0x30, 0x30, 0x30, 0x30, 0x32,
604
+            0x30, 0x35, 0x5a, 0x17, 0x0d, 0x31, 0x35, 0x31, 0x30, 0x31, 0x39, 0x30, 0x30, 0x30,
605
+            0x32, 0x30, 0x35, 0x5a, 0x30, 0x68, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
606
+            0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
607
+            0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x17,
608
+            0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0e, 0x41, 0x70, 0x70, 0x6c, 0x65,
609
+            0x20, 0x46, 0x61, 0x69, 0x72, 0x50, 0x6c, 0x61, 0x79, 0x31, 0x2b, 0x30, 0x29, 0x06,
610
+            0x03, 0x55, 0x04, 0x03, 0x13, 0x22, 0x41, 0x50, 0x4e, 0x2d, 0x57, 0x69, 0x6e, 0x2e,
611
+            0x33, 0x33, 0x33, 0x33, 0x41, 0x46, 0x31, 0x30, 0x31, 0x30, 0x32, 0x30, 0x41, 0x46,
612
+            0x30, 0x30, 0x30, 0x31, 0x41, 0x46, 0x30, 0x30, 0x30, 0x30, 0x30, 0x39, 0x30, 0x81,
613
+            0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
614
+            0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xaf,
615
+            0xbe, 0xfa, 0x47, 0xbb, 0xa7, 0xb8, 0x7b, 0x20, 0x58, 0x4b, 0xf4, 0x76, 0x53, 0x5e,
616
+            0xb8, 0x44, 0xf3, 0xe0, 0x1d, 0x90, 0x6c, 0xb6, 0xae, 0x9e, 0x94, 0x8b, 0x52, 0x67,
617
+            0xf8, 0xe9, 0x4a, 0x98, 0xbd, 0x66, 0xe5, 0x4f, 0x51, 0xf7, 0x6a, 0x1f, 0x76, 0xa8,
618
+            0x94, 0xc7, 0x3f, 0xa8, 0xf7, 0x46, 0x6f, 0xac, 0x23, 0x56, 0x29, 0x68, 0xed, 0xd0,
619
+            0x9b, 0x8c, 0x6e, 0x87, 0x47, 0xd1, 0x1d, 0xa0, 0x1a, 0x35, 0x96, 0xfd, 0xca, 0x93,
620
+            0x8c, 0x7f, 0x04, 0xcd, 0x5f, 0x1c, 0x5c, 0x61, 0x7d, 0x87, 0x4b, 0x06, 0xc0, 0x6e,
621
+            0xa2, 0x62, 0xf2, 0x57, 0x64, 0x62, 0x16, 0xcf, 0x1a, 0xbb, 0x86, 0x9c, 0x3a, 0xb1,
622
+            0x74, 0x18, 0x62, 0x33, 0xff, 0xe4, 0x61, 0x8d, 0x23, 0xaa, 0xdf, 0x14, 0x9c, 0x79,
623
+            0x87, 0xd1, 0x35, 0x97, 0x01, 0x6a, 0xf0, 0xd1, 0xb0, 0xcc, 0x9f, 0x5f, 0x0f, 0x06,
624
+            0x6b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x60, 0x30, 0x5e, 0x30, 0x0e, 0x06, 0x03,
625
+            0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x03, 0xb8, 0x30, 0x0c,
626
+            0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d,
627
+            0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x59, 0x2c, 0x9c, 0x42, 0x56,
628
+            0x6b, 0x56, 0x6f, 0xa9, 0xd9, 0x51, 0xd8, 0xe0, 0x58, 0x9d, 0x89, 0xfa, 0xa6, 0xbf,
629
+            0x41, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
630
+            0xfa, 0x0d, 0xd4, 0x11, 0x91, 0x1b, 0xe6, 0xb2, 0x4e, 0x1e, 0x06, 0x49, 0x94, 0x11,
631
+            0xdd, 0x63, 0x62, 0x07, 0x59, 0x64, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
632
+            0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x93, 0x8c, 0x71,
633
+            0xef, 0xa0, 0x1b, 0x9f, 0xc5, 0xa9, 0xcc, 0x2e, 0xec, 0x6a, 0x73, 0x99, 0xff, 0xa0,
634
+            0x7a, 0x79, 0x2b, 0x74, 0x72, 0xfc, 0xd5, 0xd7, 0x09, 0x46, 0xe2, 0x10, 0xc9, 0x57,
635
+            0x72, 0x26, 0xa8, 0xe9, 0xce, 0x3c, 0x6b, 0xb4, 0x55, 0x0f, 0xc1, 0x97, 0x40, 0x29,
636
+            0xf1, 0xdf, 0xa8, 0x6a, 0xe2, 0xcb, 0x74, 0x39, 0xf9, 0xec, 0x55, 0xb4, 0xb8, 0x9a,
637
+            0x98, 0xc5, 0x4b, 0x63, 0x97, 0x1a, 0xc5, 0x3d, 0x70, 0x85, 0x2c, 0xb3, 0x80, 0xde,
638
+            0x7a, 0xca, 0x6b, 0x36, 0xb9, 0x1d, 0x01, 0x83, 0x97, 0x12, 0x8a, 0xe0, 0x58, 0x52,
639
+            0x81, 0x44, 0xeb, 0x00, 0x76, 0xb8, 0x73, 0x06, 0x7e, 0x32, 0x48, 0x58, 0xf0, 0x8a,
640
+            0xba, 0xbe, 0x44, 0x16, 0x81, 0x90, 0x71, 0x23, 0x9f, 0x9d, 0x77, 0x84, 0x63, 0x10,
641
+            0x0f, 0x95, 0xb7, 0x9e, 0x29, 0xbd, 0xc2, 0x52, 0x0b, 0x42, 0xb1, 0x3b, 0x93,
642
+        ],
643
+    },
644
+    // APN-Win identity 00000A.
645
+    SigningIdentity {
646
+        p: [
647
+            0xe8, 0xc1, 0x04, 0xea, 0xfb, 0xd9, 0x6f, 0x57, 0x56, 0x3a, 0x59, 0xf5, 0x1a, 0x0f,
648
+            0x66, 0xaa, 0x23, 0x37, 0x53, 0x24, 0xbd, 0xb9, 0x0d, 0xe0, 0x3b, 0xf6, 0xb6, 0x04,
649
+            0x1a, 0xa6, 0xf2, 0x45, 0x99, 0xb7, 0x4d, 0x99, 0xfb, 0x0c, 0xd2, 0x4c, 0x1d, 0x0f,
650
+            0xd1, 0x32, 0x0e, 0xf3, 0x8b, 0x9b, 0x9b, 0xd6, 0xa7, 0x0c, 0x41, 0x37, 0xbc, 0xfc,
651
+            0x18, 0x12, 0x06, 0x2c, 0x1b, 0x01, 0x4a, 0xbd,
652
+        ],
653
+        q: [
654
+            0xe1, 0x69, 0xc8, 0x77, 0x52, 0xfd, 0x8e, 0x52, 0x69, 0x75, 0x29, 0xba, 0xc6, 0xef,
655
+            0x7b, 0x49, 0x68, 0x35, 0xd7, 0xea, 0xd5, 0x15, 0xa8, 0x16, 0xae, 0x64, 0xa3, 0xcf,
656
+            0xd8, 0xe9, 0xad, 0x90, 0x69, 0xc0, 0xfe, 0xdf, 0x68, 0x47, 0xfb, 0xf3, 0xfc, 0x29,
657
+            0xb1, 0x9b, 0x68, 0xfd, 0xc0, 0x14, 0x4f, 0x5e, 0xe8, 0xa6, 0xaf, 0xab, 0xed, 0xa5,
658
+            0xdf, 0xe6, 0x2a, 0x7e, 0xf9, 0x0b, 0x06, 0x3b,
659
+        ],
660
+        certificate: &[
661
+            0x30, 0x82, 0x02, 0xc5, 0x30, 0x82, 0x02, 0x2e, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
662
+            0x0d, 0x33, 0x33, 0xaf, 0x10, 0x10, 0x20, 0xaf, 0x00, 0x01, 0xaf, 0x00, 0x00, 0x10,
663
+            0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05,
664
+            0x00, 0x30, 0x7b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
665
+            0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41,
666
+            0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06,
667
+            0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65,
668
+            0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
669
+            0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x2f, 0x30, 0x2d, 0x06, 0x03, 0x55,
670
+            0x04, 0x03, 0x13, 0x26, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x46, 0x61, 0x69, 0x72,
671
+            0x50, 0x6c, 0x61, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
672
+            0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79,
673
+            0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x31, 0x30, 0x32, 0x30, 0x30, 0x30, 0x30, 0x32,
674
+            0x30, 0x36, 0x5a, 0x17, 0x0d, 0x31, 0x35, 0x31, 0x30, 0x31, 0x39, 0x30, 0x30, 0x30,
675
+            0x32, 0x30, 0x36, 0x5a, 0x30, 0x68, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
676
+            0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
677
+            0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x17,
678
+            0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0e, 0x41, 0x70, 0x70, 0x6c, 0x65,
679
+            0x20, 0x46, 0x61, 0x69, 0x72, 0x50, 0x6c, 0x61, 0x79, 0x31, 0x2b, 0x30, 0x29, 0x06,
680
+            0x03, 0x55, 0x04, 0x03, 0x13, 0x22, 0x41, 0x50, 0x4e, 0x2d, 0x57, 0x69, 0x6e, 0x2e,
681
+            0x33, 0x33, 0x33, 0x33, 0x41, 0x46, 0x31, 0x30, 0x31, 0x30, 0x32, 0x30, 0x41, 0x46,
682
+            0x30, 0x30, 0x30, 0x31, 0x41, 0x46, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x81,
683
+            0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
684
+            0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xcc,
685
+            0xf1, 0xd2, 0xc0, 0xd4, 0xc0, 0xa0, 0xc2, 0x7e, 0x00, 0xcb, 0xa6, 0xa2, 0xc5, 0x0f,
686
+            0x55, 0x85, 0xae, 0x5d, 0xa9, 0x5a, 0x4b, 0x63, 0xd4, 0x48, 0xb2, 0xb5, 0xeb, 0x48,
687
+            0xf6, 0x7e, 0x3d, 0xa3, 0x24, 0xa3, 0xf2, 0x19, 0xff, 0x61, 0x60, 0x06, 0xc8, 0x81,
688
+            0x12, 0x64, 0x31, 0xb5, 0xd0, 0x35, 0xce, 0x31, 0x53, 0x59, 0x41, 0x28, 0xe4, 0x41,
689
+            0x87, 0xb3, 0xb9, 0x36, 0x68, 0x53, 0xf7, 0x72, 0x9f, 0xcd, 0xa8, 0x0c, 0x7d, 0x4b,
690
+            0x1e, 0x42, 0x65, 0xcc, 0xc5, 0x21, 0x6b, 0xd4, 0x24, 0x2b, 0xfb, 0xec, 0x33, 0xff,
691
+            0x40, 0xf5, 0xe4, 0x33, 0xf7, 0x22, 0xf6, 0x79, 0xb7, 0x6e, 0xc9, 0xf7, 0x1b, 0xb2,
692
+            0x88, 0x0c, 0x2e, 0x1d, 0x7d, 0xd5, 0x10, 0xef, 0xef, 0xed, 0x05, 0x25, 0x0d, 0x99,
693
+            0x76, 0xfb, 0x19, 0x26, 0xd2, 0xd5, 0xa9, 0x6c, 0x29, 0xaa, 0x92, 0x4c, 0x2b, 0xa7,
694
+            0x8f, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x60, 0x30, 0x5e, 0x30, 0x0e, 0x06, 0x03,
695
+            0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x03, 0xb8, 0x30, 0x0c,
696
+            0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d,
697
+            0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x92, 0x6c, 0xf2, 0xef, 0x26,
698
+            0xb5, 0x1a, 0x38, 0x41, 0xe8, 0xba, 0xb8, 0x11, 0x0d, 0x58, 0x18, 0x51, 0x86, 0x66,
699
+            0xbb, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
700
+            0xfa, 0x0d, 0xd4, 0x11, 0x91, 0x1b, 0xe6, 0xb2, 0x4e, 0x1e, 0x06, 0x49, 0x94, 0x11,
701
+            0xdd, 0x63, 0x62, 0x07, 0x59, 0x64, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
702
+            0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x44, 0x47, 0xd1,
703
+            0x2f, 0x41, 0x3c, 0x06, 0x8d, 0x07, 0xa9, 0x7c, 0xa7, 0xaa, 0x35, 0x1c, 0x2e, 0xdf,
704
+            0x94, 0x44, 0xaa, 0x31, 0x47, 0xba, 0xf8, 0x32, 0x82, 0xef, 0xf5, 0xa1, 0xe9, 0x6e,
705
+            0xd2, 0x3f, 0x2f, 0x40, 0x3f, 0x3a, 0x53, 0xd1, 0x7e, 0xce, 0x0c, 0x2b, 0x4c, 0xb3,
706
+            0xfa, 0x07, 0x41, 0x9d, 0x22, 0xf3, 0x6a, 0x79, 0x90, 0x8c, 0xa9, 0x7c, 0xee, 0x58,
707
+            0x0b, 0x16, 0x0d, 0x36, 0x8c, 0x1c, 0x2c, 0x5e, 0x56, 0xc4, 0x5d, 0x5a, 0xff, 0x71,
708
+            0xe5, 0x0a, 0xe8, 0x6e, 0x8d, 0x98, 0x85, 0x55, 0xb7, 0xaf, 0x72, 0x3d, 0xec, 0xa5,
709
+            0xea, 0x2c, 0xfb, 0x90, 0x01, 0x75, 0x4f, 0x46, 0x10, 0x88, 0x91, 0x71, 0xf5, 0xd8,
710
+            0xe8, 0x7c, 0xd4, 0x69, 0x7f, 0x04, 0x39, 0xec, 0x65, 0x1a, 0x7c, 0x3c, 0xb0, 0xc0,
711
+            0x52, 0xf9, 0x84, 0x05, 0xf9, 0x1b, 0x47, 0xc6, 0xd2, 0x38, 0xf3, 0x6e, 0x3b,
712
+        ],
713
+    },
714
+];
715
+
716
+// FairPlay intermediate and root certificates, concatenated DER.
717
+pub(super) const CERTIFICATE_AUTHORITY_CHAIN: &[u8] = &[
718
+    0x30, 0x82, 0x03, 0x71, 0x30, 0x82, 0x02, 0x59, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x11,
719
+    0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30,
720
+    0x62, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13,
721
+    0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49,
722
+    0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x70,
723
+    0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
724
+    0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x16, 0x30, 0x14, 0x06,
725
+    0x03, 0x55, 0x04, 0x03, 0x13, 0x0d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74,
726
+    0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x37, 0x30, 0x32, 0x31, 0x34, 0x31, 0x39, 0x32,
727
+    0x30, 0x34, 0x31, 0x5a, 0x17, 0x0d, 0x31, 0x32, 0x30, 0x32, 0x31, 0x34, 0x31, 0x39, 0x32, 0x30,
728
+    0x34, 0x31, 0x5a, 0x30, 0x7b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
729
+    0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70,
730
+    0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b,
731
+    0x13, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
732
+    0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31,
733
+    0x2f, 0x30, 0x2d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x26, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20,
734
+    0x46, 0x61, 0x69, 0x72, 0x50, 0x6c, 0x61, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
735
+    0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79,
736
+    0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
737
+    0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xb2, 0x67, 0x3c,
738
+    0x5d, 0x2a, 0xe7, 0x8f, 0xf2, 0x77, 0xcf, 0xef, 0x31, 0xbc, 0xd1, 0x04, 0xfd, 0xea, 0x9f, 0xd0,
739
+    0x86, 0x29, 0x90, 0x0a, 0xa3, 0xff, 0x64, 0x4a, 0xef, 0x69, 0xf4, 0x0a, 0xb9, 0xef, 0xc4, 0xc4,
740
+    0x63, 0xca, 0x3a, 0x2d, 0x21, 0x3d, 0x52, 0x8c, 0x23, 0x89, 0x29, 0xaa, 0xdb, 0x17, 0xdc, 0xcb,
741
+    0x28, 0xc4, 0x69, 0xcd, 0x72, 0x24, 0xc2, 0x10, 0xc1, 0xf4, 0x78, 0x1d, 0x31, 0x16, 0xc5, 0xe6,
742
+    0xea, 0x19, 0x1d, 0x2a, 0x33, 0xbe, 0x80, 0xab, 0xdc, 0x11, 0x48, 0x06, 0x2a, 0x1f, 0x0e, 0x61,
743
+    0x81, 0xcd, 0x79, 0x9a, 0x5d, 0x12, 0xf4, 0x84, 0x90, 0xc8, 0x7c, 0xf6, 0x78, 0x9b, 0x52, 0xf8,
744
+    0xfa, 0xf1, 0x88, 0x6e, 0x10, 0x72, 0xf8, 0x5d, 0xcb, 0x88, 0xec, 0xb6, 0x55, 0x14, 0x97, 0xa4,
745
+    0x4d, 0x0b, 0xc1, 0x4f, 0x27, 0x67, 0x99, 0xa6, 0xa4, 0xb3, 0xd7, 0xda, 0xad, 0x02, 0x03, 0x01,
746
+    0x00, 0x01, 0xa3, 0x81, 0x9c, 0x30, 0x81, 0x99, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01,
747
+    0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
748
+    0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e,
749
+    0x04, 0x16, 0x04, 0x14, 0xfa, 0x0d, 0xd4, 0x11, 0x91, 0x1b, 0xe6, 0xb2, 0x4e, 0x1e, 0x06, 0x49,
750
+    0x94, 0x11, 0xdd, 0x63, 0x62, 0x07, 0x59, 0x64, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04,
751
+    0x18, 0x30, 0x16, 0x80, 0x14, 0x2b, 0xd0, 0x69, 0x47, 0x94, 0x76, 0x09, 0xfe, 0xf4, 0x6b, 0x8d,
752
+    0x2e, 0x40, 0xa6, 0xf7, 0x47, 0x4d, 0x7f, 0x08, 0x5e, 0x30, 0x36, 0x06, 0x03, 0x55, 0x1d, 0x1f,
753
+    0x04, 0x2f, 0x30, 0x2d, 0x30, 0x2b, 0xa0, 0x29, 0xa0, 0x27, 0x86, 0x25, 0x68, 0x74, 0x74, 0x70,
754
+    0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
755
+    0x2f, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x63, 0x61, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x72,
756
+    0x6c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00,
757
+    0x03, 0x82, 0x01, 0x01, 0x00, 0xc0, 0xa0, 0x73, 0xf8, 0x1d, 0xea, 0x1c, 0xd1, 0xcd, 0xc5, 0x86,
758
+    0x75, 0xa4, 0xbb, 0xeb, 0x40, 0xc5, 0x6a, 0x2d, 0x0c, 0xfe, 0x5b, 0xfc, 0x6e, 0xc1, 0x5b, 0xd7,
759
+    0x48, 0x7d, 0x40, 0xa9, 0x61, 0x2d, 0x4b, 0x37, 0x70, 0x38, 0xef, 0x06, 0x91, 0x4b, 0xaf, 0x11,
760
+    0xc2, 0x1f, 0x95, 0xee, 0x88, 0x33, 0x6f, 0x5f, 0x72, 0xea, 0xf6, 0xd5, 0x76, 0xb5, 0x57, 0x58,
761
+    0x71, 0xf0, 0x3e, 0x10, 0xc3, 0xd5, 0x2e, 0xbb, 0x2f, 0xa6, 0x3a, 0x73, 0xc2, 0x32, 0x65, 0x0a,
762
+    0x56, 0x04, 0x16, 0x19, 0x98, 0x4d, 0x0b, 0x78, 0x6d, 0xd0, 0xa3, 0x74, 0x64, 0x98, 0x54, 0xf4,
763
+    0xa7, 0xd7, 0x1d, 0xa2, 0xff, 0x2a, 0xc3, 0x79, 0x00, 0xb2, 0x99, 0xe7, 0xe7, 0xbb, 0xd5, 0x06,
764
+    0xa2, 0xeb, 0x49, 0x33, 0x69, 0x67, 0x41, 0x01, 0x99, 0xad, 0x68, 0xb0, 0xd3, 0x7a, 0xf4, 0x95,
765
+    0xe0, 0xfd, 0x24, 0x88, 0x2a, 0x10, 0xe7, 0xa3, 0x68, 0xff, 0xad, 0x7b, 0xfa, 0xd9, 0xba, 0xf1,
766
+    0xa5, 0x7f, 0xca, 0x93, 0xa2, 0xce, 0x03, 0x37, 0x03, 0x66, 0x85, 0x93, 0x05, 0x1b, 0x31, 0xf6,
767
+    0x75, 0x82, 0x93, 0x2f, 0xd3, 0xf0, 0xda, 0x39, 0x37, 0x3d, 0x5f, 0xfe, 0xba, 0xcd, 0x9a, 0x70,
768
+    0xc0, 0x06, 0x8b, 0x22, 0xee, 0xa9, 0xce, 0x04, 0x6e, 0x24, 0x69, 0x3b, 0x16, 0x52, 0xa5, 0xc0,
769
+    0xf2, 0xc0, 0xae, 0x43, 0x70, 0x84, 0xbb, 0x21, 0x91, 0x43, 0xcb, 0xbb, 0xb7, 0xea, 0x5b, 0xba,
770
+    0x93, 0xe0, 0xb7, 0x77, 0x89, 0xef, 0x4d, 0x56, 0x04, 0x33, 0x5d, 0xce, 0x5c, 0x59, 0x31, 0xa7,
771
+    0xd7, 0x3b, 0x45, 0x56, 0x11, 0xcd, 0xae, 0xcb, 0x9b, 0x0e, 0xa0, 0xcf, 0xdc, 0x93, 0xa8, 0xca,
772
+    0xc5, 0x58, 0x78, 0x00, 0x05, 0xd9, 0x99, 0xab, 0xd6, 0x5e, 0x87, 0xea, 0x92, 0x73, 0x34, 0x54,
773
+    0xa3, 0x93, 0x18, 0xa4, 0x83, 0x30, 0x82, 0x04, 0xbb, 0x30, 0x82, 0x03, 0xa3, 0xa0, 0x03, 0x02,
774
+    0x01, 0x02, 0x02, 0x01, 0x02, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
775
+    0x01, 0x05, 0x05, 0x00, 0x30, 0x62, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
776
+    0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70,
777
+    0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04,
778
+    0x0b, 0x13, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
779
+    0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79,
780
+    0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0d, 0x41, 0x70, 0x70, 0x6c, 0x65,
781
+    0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x30, 0x34,
782
+    0x32, 0x35, 0x32, 0x31, 0x34, 0x30, 0x33, 0x36, 0x5a, 0x17, 0x0d, 0x33, 0x35, 0x30, 0x32, 0x30,
783
+    0x39, 0x32, 0x31, 0x34, 0x30, 0x33, 0x36, 0x5a, 0x30, 0x62, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
784
+    0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
785
+    0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24,
786
+    0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72,
787
+    0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
788
+    0x72, 0x69, 0x74, 0x79, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0d, 0x41,
789
+    0x70, 0x70, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22,
790
+    0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03,
791
+    0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xe4, 0x91, 0xa9,
792
+    0x09, 0x1f, 0x91, 0xdb, 0x1e, 0x47, 0x50, 0xeb, 0x05, 0xed, 0x5e, 0x79, 0x84, 0x2d, 0xeb, 0x36,
793
+    0xa2, 0x57, 0x4c, 0x55, 0xec, 0x8b, 0x19, 0x89, 0xde, 0xf9, 0x4b, 0x6c, 0xf5, 0x07, 0xab, 0x22,
794
+    0x30, 0x02, 0xe8, 0x18, 0x3e, 0xf8, 0x50, 0x09, 0xd3, 0x7f, 0x41, 0xa8, 0x98, 0xf9, 0xd1, 0xca,
795
+    0x66, 0x9c, 0x24, 0x6b, 0x11, 0xd0, 0xa3, 0xbb, 0xe4, 0x1b, 0x2a, 0xc3, 0x1f, 0x95, 0x9e, 0x7a,
796
+    0x0c, 0xa4, 0x47, 0x8b, 0x5b, 0xd4, 0x16, 0x37, 0x33, 0xcb, 0xc4, 0x0f, 0x4d, 0xce, 0x14, 0x69,
797
+    0xd1, 0xc9, 0x19, 0x72, 0xf5, 0x5d, 0x0e, 0xd5, 0x7f, 0x5f, 0x9b, 0xf2, 0x25, 0x03, 0xba, 0x55,
798
+    0x8f, 0x4d, 0x5d, 0x0d, 0xf1, 0x64, 0x35, 0x23, 0x15, 0x4b, 0x15, 0x59, 0x1d, 0xb3, 0x94, 0xf7,
799
+    0xf6, 0x9c, 0x9e, 0xcf, 0x50, 0xba, 0xc1, 0x58, 0x50, 0x67, 0x8f, 0x08, 0xb4, 0x20, 0xf7, 0xcb,
800
+    0xac, 0x2c, 0x20, 0x6f, 0x70, 0xb6, 0x3f, 0x01, 0x30, 0x8c, 0xb7, 0x43, 0xcf, 0x0f, 0x9d, 0x3d,
801
+    0xf3, 0x2b, 0x49, 0x28, 0x1a, 0xc8, 0xfe, 0xce, 0xb5, 0xb9, 0x0e, 0xd9, 0x5e, 0x1c, 0xd6, 0xcb,
802
+    0x3d, 0xb5, 0x3a, 0xad, 0xf4, 0x0f, 0x0e, 0x00, 0x92, 0x0b, 0xb1, 0x21, 0x16, 0x2e, 0x74, 0xd5,
803
+    0x3c, 0x0d, 0xdb, 0x62, 0x16, 0xab, 0xa3, 0x71, 0x92, 0x47, 0x53, 0x55, 0xc1, 0xaf, 0x2f, 0x41,
804
+    0xb3, 0xf8, 0xfb, 0xe3, 0x70, 0xcd, 0xe6, 0xa3, 0x4c, 0x45, 0x7e, 0x1f, 0x4c, 0x6b, 0x50, 0x96,
805
+    0x41, 0x89, 0xc4, 0x74, 0x62, 0x0b, 0x10, 0x83, 0x41, 0x87, 0x33, 0x8a, 0x81, 0xb1, 0x30, 0x58,
806
+    0xec, 0x5a, 0x04, 0x32, 0x8c, 0x68, 0xb3, 0x8f, 0x1d, 0xde, 0x65, 0x73, 0xff, 0x67, 0x5e, 0x65,
807
+    0xbc, 0x49, 0xd8, 0x76, 0x9f, 0x33, 0x14, 0x65, 0xa1, 0x77, 0x94, 0xc9, 0x2d, 0x02, 0x03, 0x01,
808
+    0x00, 0x01, 0xa3, 0x82, 0x01, 0x7a, 0x30, 0x82, 0x01, 0x76, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
809
+    0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d,
810
+    0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55,
811
+    0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x2b, 0xd0, 0x69, 0x47, 0x94, 0x76, 0x09, 0xfe, 0xf4, 0x6b,
812
+    0x8d, 0x2e, 0x40, 0xa6, 0xf7, 0x47, 0x4d, 0x7f, 0x08, 0x5e, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
813
+    0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x2b, 0xd0, 0x69, 0x47, 0x94, 0x76, 0x09, 0xfe, 0xf4,
814
+    0x6b, 0x8d, 0x2e, 0x40, 0xa6, 0xf7, 0x47, 0x4d, 0x7f, 0x08, 0x5e, 0x30, 0x82, 0x01, 0x11, 0x06,
815
+    0x03, 0x55, 0x1d, 0x20, 0x04, 0x82, 0x01, 0x08, 0x30, 0x82, 0x01, 0x04, 0x30, 0x82, 0x01, 0x00,
816
+    0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x05, 0x01, 0x30, 0x81, 0xf2, 0x30, 0x2a,
817
+    0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1e, 0x68, 0x74, 0x74, 0x70,
818
+    0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f,
819
+    0x6d, 0x2f, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x63, 0x61, 0x2f, 0x30, 0x81, 0xc3, 0x06, 0x08, 0x2b,
820
+    0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x02, 0x30, 0x81, 0xb6, 0x1a, 0x81, 0xb3, 0x52, 0x65, 0x6c,
821
+    0x69, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x63, 0x65,
822
+    0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x62, 0x79, 0x20, 0x61, 0x6e, 0x79,
823
+    0x20, 0x70, 0x61, 0x72, 0x74, 0x79, 0x20, 0x61, 0x73, 0x73, 0x75, 0x6d, 0x65, 0x73, 0x20, 0x61,
824
+    0x63, 0x63, 0x65, 0x70, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65,
825
+    0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x62, 0x6c, 0x65,
826
+    0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x74, 0x65, 0x72, 0x6d, 0x73, 0x20,
827
+    0x61, 0x6e, 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6f,
828
+    0x66, 0x20, 0x75, 0x73, 0x65, 0x2c, 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
829
+    0x74, 0x65, 0x20, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x65,
830
+    0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x61, 0x63,
831
+    0x74, 0x69, 0x63, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e,
832
+    0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03,
833
+    0x82, 0x01, 0x01, 0x00, 0x5c, 0x36, 0x99, 0x4c, 0x2d, 0x78, 0xb7, 0xed, 0x8c, 0x9b, 0xdc, 0xf3,
834
+    0x77, 0x9b, 0xf2, 0x76, 0xd2, 0x77, 0x30, 0x4f, 0xc1, 0x1f, 0x85, 0x83, 0x85, 0x1b, 0x99, 0x3d,
835
+    0x47, 0x37, 0xf2, 0xa9, 0x9b, 0x40, 0x8e, 0x2c, 0xd4, 0xb1, 0x90, 0x12, 0xd8, 0xbe, 0xf4, 0x73,
836
+    0x9b, 0xee, 0xd2, 0x64, 0x0f, 0xcb, 0x79, 0x4f, 0x34, 0xd8, 0xa2, 0x3e, 0xf9, 0x78, 0xff, 0x6b,
837
+    0xc8, 0x07, 0xec, 0x7d, 0x39, 0x83, 0x8b, 0x53, 0x20, 0xd3, 0x38, 0xc4, 0xb1, 0xbf, 0x9a, 0x4f,
838
+    0x0a, 0x6b, 0xff, 0x2b, 0xfc, 0x59, 0xa7, 0x05, 0x09, 0x7c, 0x17, 0x40, 0x56, 0x11, 0x1e, 0x74,
839
+    0xd3, 0xb7, 0x8b, 0x23, 0x3b, 0x47, 0xa3, 0xd5, 0x6f, 0x24, 0xe2, 0xeb, 0xd1, 0xb7, 0x70, 0xdf,
840
+    0x0f, 0x45, 0xe1, 0x27, 0xca, 0xf1, 0x6d, 0x78, 0xed, 0xe7, 0xb5, 0x17, 0x17, 0xa8, 0xdc, 0x7e,
841
+    0x22, 0x35, 0xca, 0x25, 0xd5, 0xd9, 0x0f, 0xd6, 0x6b, 0xd4, 0xa2, 0x24, 0x23, 0x11, 0xf7, 0xa1,
842
+    0xac, 0x8f, 0x73, 0x81, 0x60, 0xc6, 0x1b, 0x5b, 0x09, 0x2f, 0x92, 0xb2, 0xf8, 0x44, 0x48, 0xf0,
843
+    0x60, 0x38, 0x9e, 0x15, 0xf5, 0x3d, 0x26, 0x67, 0x20, 0x8a, 0x33, 0x6a, 0xf7, 0x0d, 0x82, 0xcf,
844
+    0xde, 0xeb, 0xa3, 0x2f, 0xf9, 0x53, 0x6a, 0x5b, 0x64, 0xc0, 0x63, 0x33, 0x77, 0xf7, 0x3a, 0x07,
845
+    0x2c, 0x56, 0xeb, 0xda, 0x0f, 0x21, 0x0e, 0xda, 0xba, 0x73, 0x19, 0x4f, 0xb5, 0xd9, 0x36, 0x7f,
846
+    0xc1, 0x87, 0x55, 0xd9, 0xa7, 0x99, 0xb9, 0x32, 0x42, 0xfb, 0xd8, 0xd5, 0x71, 0x9e, 0x7e, 0xa1,
847
+    0x52, 0xb7, 0x1b, 0xbd, 0x93, 0x42, 0x24, 0x12, 0x2a, 0xc7, 0x0f, 0x1d, 0xb6, 0x4d, 0x9c, 0x5e,
848
+    0x63, 0xc8, 0x4b, 0x80, 0x17, 0x50, 0xaa, 0x8a, 0xd5, 0xda, 0xe4, 0xfc, 0xd0, 0x09, 0x07, 0x37,
849
+    0xb0, 0x75, 0x75, 0x21,
850
+];
... ...
@@ -16,3 +16,9 @@ serde = { version = "1.0.228", features = ["derive"] }
16 16
 serde_bytes = "0.11"
17 17
 sys-locale = "0.3.2"
18 18
 uuid = { version = "1.19", features = ["v4"] }
19
+
20
+[dev-dependencies]
21
+android-coreadi.workspace = true
22
+
23
+tokio = { version = "1.0", features = ["full"] }
24
+env_logger = "0.11.11"
... ...
@@ -0,0 +1,146 @@
1
+use adi::proxy::ADIProxy;
2
+use grandslam::bundle_information::APPLE_TV_BUNDLE_INFORMATION;
3
+use grandslam::device::Device;
4
+use grandslam::http_session::AnisetteHTTPSession;
5
+use grandslam::{AccountHTTPSession, AuthOutcome};
6
+use std::env;
7
+use xcode::{ViewDeveloperAction, XCODE_BUNDLE_INFORMATION, XcodeSession};
8
+
9
+fn build_device() -> Device {
10
+    // Fake mac
11
+    if cfg!(target_os = "windows") {
12
+        // Windows anisette provisioning endpoints wants you to use an appropriate Windows Client-Info.
13
+        // Apple doesn't care about the fact you are running Xcode on Windows.
14
+        let operating_system = "Windows";
15
+        let system_version = "10.0.18362/SP0.0.18362";
16
+        let system_edition = "Win10 Pro";
17
+        let system_arch = "x64";
18
+
19
+        Device {
20
+            device_model: "PC".to_string(),
21
+            operating_system_information: format!(
22
+                "{}; {}; {}; {}",
23
+                operating_system, system_version, system_edition, system_arch
24
+            ),
25
+            // It should look like a FairPlay GUID.
26
+            // It is built with a certain logic too, but IIRC it's basically hashes all the way.
27
+            // device_uuid: "00000000.00000000.00000000.00000000.00000000.00000000.00000000".to_string(),
28
+
29
+            // That one is not possible in real situations. But Apple also accepts it /shrug
30
+            device_uuid: "A8B31C86-359B-4D95-8950-BA5DD8FFC46F".to_string(),
31
+        }
32
+    } else {
33
+        Device {
34
+            device_model: "Mac16,8".to_string(),
35
+            operating_system_information: "macOS;15.7.3;24G419".to_string(),
36
+            device_uuid: "229B41B5-93B0-5632-9E1A-D4EF0669C3C1".to_string(),
37
+        }
38
+    }
39
+}
40
+
41
+async fn grandslam_test(
42
+    proxy: &dyn ADIProxy,
43
+    apple_id: &str,
44
+    password: &str,
45
+) -> Result<(), Box<dyn std::error::Error>> {
46
+    // proxy.set_android_id("0123456789012345")?;
47
+    // proxy.set_provisioning_path(c"./adi_files")?;
48
+
49
+    let device = build_device();
50
+
51
+    // println!("{:#02X?}", proxy.get_all_provisioned_accounts());
52
+
53
+    let http_session = AnisetteHTTPSession::new(
54
+        grandslam::http_session(device, XCODE_BUNDLE_INFORMATION).await?,
55
+        proxy,
56
+    );
57
+
58
+    if !proxy.is_machine_provisioned(grandslam::GRANDSLAM_DSID)? {
59
+        grandslam::provision(&http_session).await?;
60
+    }
61
+
62
+    // Here we should fetch_auth_mode first to know if we should log in with a password.
63
+    let auth_outcome = grandslam::login(&http_session, apple_id, password).await?;
64
+
65
+    match &auth_outcome {
66
+        AuthOutcome::Success(server_provided_data)
67
+        | AuthOutcome::SecondaryActionRequired(Some(server_provided_data), _) => {
68
+            if let (
69
+                Some(alt_dsid),
70
+                Some(idms_token),
71
+                Some(session_key),
72
+                Some(cookie),
73
+            ) = (
74
+                server_provided_data.alt_dsid(),
75
+                server_provided_data.idms_token(),
76
+                server_provided_data.session_key(),
77
+                server_provided_data.cookie(),
78
+            ) {
79
+                let http_session =
80
+                    AccountHTTPSession::new(http_session, alt_dsid);
81
+
82
+                let xcode_token = http_session.get_app_token(&idms_token, &session_key, &cookie).await?;
83
+                let xcode_session = XcodeSession::new(http_session, xcode_token);
84
+
85
+                let developer =
86
+                    xcode_session
87
+                        .perform_developer_action(ViewDeveloperAction {})
88
+                        .await??;
89
+
90
+                println!("{:?}", developer);
91
+            } else {
92
+                todo!()
93
+            }
94
+        }
95
+        AuthOutcome::SecondaryActionRequired(_, _)
96
+        | AuthOutcome::AnisetteResyncRequired(_)
97
+        | AuthOutcome::AnisetteReprovisionRequired
98
+        | AuthOutcome::UrlSwitchingRequired(_) => todo!(),
99
+    }
100
+
101
+    Ok(())
102
+}
103
+
104
+#[tokio::main]
105
+async fn main() -> Result<(), Box<dyn std::error::Error>> {
106
+    env_logger::init();
107
+
108
+    let apple_id = env::var("APPLE_ID")?;
109
+    let password = env::var("APPLE_PASSWORD")?;
110
+
111
+    /*
112
+    // Just re-use system Anisette if available
113
+    #[cfg(target_os = "macos")]
114
+    // on Intel Macs, we could also use a CoreADI.framework taken from an old iTunes version.
115
+    let proxy = adid_proxy::ADIdProxy::connect();
116
+
117
+    #[cfg(target_os = "windows")]
118
+    let library = dlopen2::symbor::Library::open("C:\\Program Files\\iTunes\\CoreADI64.dll")?;
119
+    #[cfg(target_os = "windows")]
120
+    let proxy = {
121
+        let proxy = library_coreadi::LibraryCoreADIProxy::new(&library)?;
122
+
123
+        core_adi::CoreADIADIProxy::initialize(&proxy)?;
124
+
125
+        proxy
126
+    };
127
+
128
+    #[cfg(not(any(target_os = "windows", target_os = "macos")))]
129
+    // */
130
+
131
+    let proxy = {
132
+        let core_adi_data = std::fs::read("nodistrib/lib/arm64-v8a/libCoreADI.so")?;
133
+        let proxy = android_coreadi::AndroidCoreADIProxy::load_library(core_adi_data)?;
134
+        adi::core_adi::CoreADIADIProxy::initialize(&proxy)?;
135
+        proxy.set_android_id("0123456789012345")?;
136
+        proxy.set_provisioning_path(c"./adi_files")?;
137
+
138
+        proxy
139
+    };
140
+
141
+    println!("{:#?}", proxy.get_all_provisioned_accounts());
142
+
143
+    grandslam_test(&proxy, &apple_id, &password).await?;
144
+
145
+    Ok(())
146
+}
0 147