Final Merge#791
Merged
Merged
Conversation
…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…
There was a problem hiding this comment.
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
marked this pull request as ready for review
July 12, 2026 15:14
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.