feat: preserve E2EE key sets during setup - #4270
Open
marinofaggiana wants to merge 17 commits into
Open
Conversation
Archive active E2EE credentials in the Keychain before setup resets or certificate renewal, while deduplicating snapshots and preserving explicit full cleanup. Add unit coverage for complete, duplicate, and partial key-set archives, and update resolved package versions. Signed-off-by: Marino Faggiana <marino.faggiana@nextcloud.com>
marinofaggiana
marked this pull request as draft
August 20, 2026 07:17
Signed-off-by: Marino Faggiana <marino.faggiana@nextcloud.com>
Signed-off-by: Marino Faggiana <marino.faggiana@nextcloud.com>
Signed-off-by: Marino Faggiana <marino.faggiana@nextcloud.com>
Reuse the encrypted root key only for child metadata and verify empty-user signatures with the current certificate. Update Firebase dependencies to 12.18.0. Signed-off-by: Marino Faggiana <marino.faggiana@nextcloud.com>
Block metadata recovery and destructive operations when only archived or unavailable keys can decrypt the folder. Allow explicit initial metadata creation for newly encrypted folders. Signed-off-by: Marino Faggiana <marino.faggiana@nextcloud.com>
Pin Firebase and GoogleAppMeasurement to 12.17.0. Signed-off-by: Marino Faggiana <marino.faggiana@nextcloud.com>
Detect and replace stale server key sets while preserving archived keys for read-only access. Validate write operations and route encrypted media folder deletion through the E2EE flow. Signed-off-by: Marino Faggiana <marino.faggiana@nextcloud.com>
Signed-off-by: Marino Faggiana <marino.faggiana@nextcloud.com>
Signed-off-by: Marino Faggiana <marino.faggiana@nextcloud.com>
…were-removed-or-changed-on-another-device-in-the-client
Prompt for the account password before deleting E2EE keys or renewing certificates. Update NextcloudKit to the password-parameter branch. Signed-off-by: Marino Faggiana <marino.faggiana@nextcloud.com>
Update NextcloudKit and Firebase package revisions. Signed-off-by: Marino Faggiana <marino.faggiana@nextcloud.com>
Use the server public key only to authenticate certificates, and compare embedded user keys when detecting key changes. Verify decrypted private keys match the user certificate before storing or uploading them. Signed-off-by: Marino Faggiana <marino.faggiana@nextcloud.com>
Signed-off-by: Marino Faggiana <marino.faggiana@nextcloud.com>
marinofaggiana
marked this pull request as ready for review
August 25, 2026 07:17
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.
Summary
This PR allows the iOS client to safely handle E2EE account keys that are removed or replaced on another device.
Previously, the client assumed that an account had a single permanent key set. When the server-side user keys changed, storage encrypted with the previous keys could become inaccessible, while the client could continue treating its local key as active.
The client now preserves previous key sets as immutable Keychain snapshots. Storage that can only be decrypted with an archived key remains accessible as read-only, while the current server key set is used for new read/write storage.
Changes
active: read/write;archived: read-only;unavailable: cannot decrypt.+button inside E2EE folders resolved with an archived key.+menu when the local E2EE configuration changes.User-visible behavior
When account keys change from
K1toK2on another device:K1is archived before any local key is replaced;K2passphrase;K2becomes active;K1remains readable but read-only;K2is read/write.If the passphrase is incorrect or the update is cancelled,
K2is not stored and the previous storage remains accessible through the archivedK1key set.Testing
Manual key-rotation test
K1.K2on the second device.K1E2EE folder on the first device.K2passphrase.K1file remained readable;+button was disabled.K2passphrase and confirmed that:K2became the active key set;K1folder remained readable and read-only;K2remained read/write;+button reflected the active/read-only state correctly.+menu without requiring a manual reload.Automated coverage
Added unit coverage for:
🤖 AI (if applicable)