Skip to content

Final Merge#791

Merged
prathieshna merged 18 commits into
nextfrom
temp/next-prod-release-8th-june-2026
Jul 13, 2026
Merged

Final Merge#791
prathieshna merged 18 commits into
nextfrom
temp/next-prod-release-8th-june-2026

Conversation

@prathieshna

Copy link
Copy Markdown

No description provided.

Prathieshna Vekneswaran and others added 17 commits June 1, 2026 07:21
…rary and embedded manifests.

Specific changes:
- Integrated `com.github.contentauth:c2pa-android` library to handle Content Authenticity (C2PA).
- Removed `rust-c2pa-ffi` directory and associated JNI wrappers, Cargo configurations, and custom Gradle build tasks.
- Implemented `ProofmodeC2paManager` to manage embedded manifest signing using software-backed EC keys and self-signed X.509 certificate chains via BouncyCastle.
- Updated `CameraViewModel` to embed C2PA manifests directly into media files (JPEG/MP4) immediately after capture, replacing the previous sidecar approach.
- Removed "sidecar" manifest logic (separate `.c2pa.json` files) across the application, including `C2paHelper`, `WebDavConduit`, and `FileCleanupHelper`.
- Removed `C2paKeyStore` and associated security migration logic in favor of the new certificate management in `ProofmodeC2paManager`.
- Added BouncyCastle dependencies (`bcprov-jdk18on`, `bcpkix-jdk18on`) to support cryptographic operations for manifest signing.
- Simplified `SaveApp` and `HomeActivity` initialization logic to use the new manager.
Specific changes:

**ProofMode Integration**
- Added `ProofCompanionGenerator` to create verification metadata, including `.proof.json`, PGP signatures (`.asc`), and OpenTimestamps (`.ots`) files.
- Implemented PGP key pair generation and storage using Bouncy Castle, supporting detached signatures for both media and metadata.
- Added logic to populate proof JSON with ProofMode v1 fields, including hardware details and EXIF-derived location data.
- Integrated OpenTimestamps (OTS) to submit media hashes to a remote calendar and store the resulting timestamp proof.

**Upload & Infrastructure**
- Updated `WebDavConduit` to automatically detect and upload companion files during the media upload process.
- Added `getProofFiles()` to the base `Conduit` class to facilitate metadata generation at upload time.
- Added `org.bouncycastle:bcpg-jdk18on` dependency for OpenPGP support.
- Initialized `ProofCompanionGenerator` in the application class to ensure PGP keys are ready for use.
… and improve metadata reliability.

Specific changes:
- **C2PA Security & Performance**:
    - Implemented encryption-at-rest for C2PA private keys using AES-256-GCM with wrap keys stored in Android Keystore.
    - Optimized signing workflow to use `FileStream`, preventing large files from being loaded entirely into memory.
    - Added a post-sign verification step to ensure C2PA manifests are correctly embedded before modifying original files.
    - Updated certificate profiles to use `id-kp-documentSigning` (RFC 9336) and improved serial number generation.

- **Proof Generation & PGP**:
    - Decoupled proof generation into local capture-time signing (PGP/JSON) and upload-time network tasks (OTS).
    - Migrated PGP keys from RSA to Ed25519 and implemented streaming PGP signing.
    - Added Android Keystore-backed encryption for the PGP secret key ring.
    - Implemented a persistent retry queue (`pending_ots.txt`) for OpenTimestamps submissions to handle network failures.

- **Metadata & EXIF**:
    - Enhanced EXIF metadata with UTC offset tags (`TAG_OFFSET_TIME`) for forensic timestamp accuracy.
    - Improved `CellInfo` collection by filtering out `Int.MAX_VALUE` sentinel values.
    - Standardized capture time extraction using `ExifInterface` for consistency between proof JSON and C2PA manifests.

- **Storage & Cleanup**:
    - Updated `WebDavConduit` to recursively delete local proof companion files after successful uploads.
    - Modified `Conduit.getProofFiles` to be a suspend function to support asynchronous OTS preparation.
Specific changes:
- Transitioned from software-only signing to a two-key design to ensure media content is signed within the Android Keystore TEE.
- Implemented `SIGNING_KEY_ALIAS` for a persistent EC P-256 key in secure hardware, ensuring private key material never leaves the TEE.
- Retained a software-based CA key (encrypted at rest via AES-256-GCM) used solely to sign leaf certificates that carry the hardware public key.
- Updated `embedProof` to use `Signer.withCallback`, bypassing issues with `KeyStoreSigner` by performing manual signing via `Signature.getInstance("SHA256withECDSA")`.
- Added `generateKeystoreSigningKey` and `keystoreSign` to manage the hardware key lifecycle and signing operations.
- Refactored C2PA assertion JSON generation (Actions, CreativeWork, Location, Network) for better performance and reduced string allocations.
- Enhanced error handling and recovery for Keystore wrap-key loss scenarios.
Specific changes:

Proofmode/C2PA:
- Implement `certMatchesKeystoreKey` to verify that on-disk certificates match the current Android Keystore signing key, preventing the use of stale or orphaned cert files.
- Update `ensureC2paState` to trigger a full state regeneration if a certificate-key mismatch is detected.
- Explicitly use the "AndroidKeyStoreBCWorkaround" provider for ECDSA signatures to ensure consistent dispatch to hardware-backed Keystore across different OEM builds.

OpenTimestamps:
- Introduce a cap of 500 entries (`OTS_QUEUE_MAX`) for the pending OTS hash queue.
- Implement an eviction policy in `enqueuePendingOts` to drop the oldest entries when the limit is reached, ensuring bounded storage usage.
Specific changes:
- Replaced `SimpleDateFormat` with thread-safe `java.time.DateTimeFormatter` and `Instant` across `ProofmodeC2paManager` and `ProofCompanionGenerator` to ensure safety during concurrent coroutine execution.
- Implemented `ensureUsableSigningKey` in `ProofmodeC2paManager` to perform a test signature, allowing the system to detect and regenerate stale or unusable Keystore keys following app upgrades.
- Enhanced `ProofmodeC2paManager.embedProof` to ensure partial temporary files are deleted if an exception occurs during the signing process.
- Refactored PEM certificate parsing in `certMatchesKeystoreKey` for better readability and reliability.
- Updated `enqueuePendingOts` in `ProofCompanionGenerator` with thread synchronization and duplicate entry prevention.
- Refined the OTS queue management to consistently bound storage by dropping oldest entries when reaching the maximum limit.
- Updated EXIF metadata parsing to use `java.time` APIs for consistency with the rest of the signing pipeline.
- Refactored `observeBySubmission` and `observeByArchive` to use a simple `id ASC` sort order, removing complex status-based prioritization logic.
- Updated `getQueueWithErrorsLast` to sort by `id ASC` instead of `id DESC` for more predictable queue processing.
Specific changes:
- Updated `SettingsScreen` and `C2paScreen` to use new Proofmode-specific string resources for titles, summaries, and descriptions.
- Updated introductory text and links in `strings.xml` to refer to Proofmode and point to `proofmode.org` instead of `c2pa.org`.
- Added new string resources for Proofmode branding while maintaining compatibility for localization.
- Updated the "Learn More" URL for content authenticity to point to the Proofmode website.
- Drop support for `armeabi-v7a` as all supported devices for `minSdk 29` (Android 10) use 64-bit hardware.
- Move `ndk` configuration block to `defaultConfig` to ensure consistent ABI filtering across all build variants.
- Add a check for the existence of the `proof_companions` directory before attempting to prepare files for upload.
- Return an empty list if the directory is missing to support gallery imports, which do not generate proof companion files.
… file generation.

Specific changes:

**Proof Generation & Metadata:**
- Expanded `ProofCompanionGenerator` to generate `.csv` proof files and corresponding PGP signatures (`.csv.asc`) alongside existing JSON proofs.
- Added a dynamically generated `HowToVerifyProofData.txt` to the proof bundle with instructions for manual GPG, OpenTimestamps, and Play Integrity verification.
- Refactored metadata extraction into `buildProofFields` to include richer device and network information (e.g., Brand, Model, Network Type, IPv4/IPv6, CellInfo) directly from `CaptureMetadata`.
- Updated `CameraViewModel` to pass live capture metadata to the proof generator, ensuring sensor and device fields are preserved without relying solely on EXIF.

**Google Play Integrity (GST):**
- Introduced `SafetyNetHelper` with flavor-specific implementations:
    - **GMS:** Requests a Play Integrity token (GST) using a nonce derived from the media hash and saves it to a `.gst` file.
    - **FOSS:** Provides a no-op stub for environments without Google Mobile Services.
- Added `com.google.android.play:integrity` dependency to the GMS build configuration.

**Networking & Utilities:**
- Updated OpenTimestamps (OTS) submission to use `application/octet-stream` for raw hash uploads.
- Implemented CSV escaping logic to handle special characters and line breaks in metadata fields.
- Included the new `.csv`, `.gst`, and instruction files in the list of companions prepared for upload.
…-on-new-requirements

[WIP] Implement Play Integrity attestation and expand proof companion…

@github-advanced-security github-advanced-security AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

detekt found more than 20 potential problems in the proposed changes. Check the Files changed tab for more details.

- Modified metadata upload logic to throw an exception if all retries fail, instead of logging a non-fatal error.
- Ensures that failure to upload metadata triggers a job retry, where `isAlreadyUploaded()` will skip existing content and re-attempt only the metadata upload.
@prathieshna
prathieshna marked this pull request as ready for review July 12, 2026 15:14
@prathieshna
prathieshna merged commit df76626 into next Jul 13, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants