Skip to content

TheDhejavu/appattest-rs

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

29 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

appattest-rs

A Rust module for validating Apple App Attestations and Assertions, ensuring the integrity and authenticity of apps running on iOS devices.

Overview

appattest-rs is a rust-based implementation for integrating Apple's App Attestation mechanism into your server-side applications. This allows you to verify that the app communicating with your server is genuine and has not been modified. This crate is particularly useful for enhancing the security of your iOS applications by utilizing Apple's DeviceCheck capabilities.

flowchart LR
    A[Start] --> B[Decode Base64 CBOR Data]
    B --> C{Is Decoding Successful?}
    C -->|Yes| D[Create Assertion or Attestation Object]
    C -->|No| E[Decoding Failure and Exit]

    D --> F{Verify Assertion/Attestation}
    F -->|Yes| G[Verification Successful]
    F -->|No| H[Verification Failure]

    G --> I[End Process]
    H --> I

    style A fill:#f9f,stroke:#333,stroke-width:2px,color:black
    style I fill:#ccf,stroke:#333,stroke-width:2px,color:black
    style G fill:#cfc,stroke:#393,stroke-width:2px,color:black
    style H fill:#f99,stroke:#933,stroke-width:2px,color:black
    style E fill:#f99,stroke:#933,stroke-width:2px,color:black

Loading

Features

  • Validation of App Attestations: Ensure that the attestation received from an iOS device is valid and conforms to Apple's guidelines.
  • Assertion Verification: Verify assertions made by iOS applications to confirm their authenticity.

Installation

Add appattest-rs to the [dependencies] section of your Cargo.toml:

...

[dependencies]
appattest-rs = "0.1.0"

...

Alternatively, with cargo add:

❯❯ cargo add appattest-rs

Usage

Verifying an Attestation

src/main.rs:

use appattest_rs::attestation::Attestation;

fn main() {
    let app_id = "<APPLE_TEAM_ID>.<APPLE_APP_ID>"; // replace this with yours. E.g 9000738U8.auth.iphone.com
    let key_id = "ZSSh9dOqo0iEvnNOtTGIHaue8n4RN/Dd8FiYFphsKTI=";
    let challenge = "5b3b2303-e650-4a56-a9ec-33e3e2a90d14";
    let base64_cbor_data = "o2NmbXRv...";

    let attestation_result = Attestation::from_base64(base64_cbor_data);
    match attestation_result {
        Ok(attestation) => {
            match attestation.verify(challenge, app_id, key_id) {
                Ok(_) => println!("Verification successful!"),
                Err(e) => println!("Verification failed: {:?}", e),
            }
        },
        Err(e) => println!("Failed to decode and create attestation: {:?}", e),
    }
}

Verifying an Assertion

src/main.rs:

use appattest_rs::assertion::Assertion;
use base64::{engine::general_purpose, Engine};

fn main() {
    let client_data_json = r#"{"challenge": "5b3b2303-e650-4a56-a9ec-33e3e2a90d14"}"#.as_bytes().to_vec();
    let app_id = "<APPLE_TEAM_ID>.<APPLE_APP_ID>"; // replace this with yours. E.g 9000738U8.auth.iphone.com
    let public_key_base64 = "BLROJkpk8NoHVHAnkLOKWUrc4MhyMkATpDyDwjEk82o+uf+KCQiDoHZdlcJ1ff5HPgK7Jd/pTA3cyKOq5MYM6Gs=";
    let public_key_byte = general_purpose::STANDARD.decode(public_key_base64).expect("unable to decode public key");
    let previous_counter = 0;
    let stored_challenge = "5b3b2303-e650-4a56-a9ec-33e3e2a90d14";
    let base64_cbor_data = "omlzaWdu....";

    let assertion_result = Assertion::from_base64(base64_cbor_data);
    match assertion_result {
        Ok(assertion) => {
            match assertion.verify(client_data_json, app_id, public_key_byte, previous_counter, stored_challenge) {
                Ok(_) => println!("Verification successful!"),
                Err(e) => println!("Verification failed: {:?}", e),
            }
        },
        Err(e) => println!("Failed to decode and create assertion: {:?}", e),
    }
}

References

For more detailed documentation, visit the following resources: