fix: implement session key reuse for move/rename operations#3
Open
mcanevet wants to merge 2 commits intorclone:masterfrom
Open
fix: implement session key reuse for move/rename operations#3mcanevet wants to merge 2 commits intorclone:masterfrom
mcanevet wants to merge 2 commits intorclone:masterfrom
Conversation
This commit fixes two bugs that prevent file uploads to Proton Drive:
--- Bug 1: handleRevisionConflict ignores ReplaceExistingDraft when
GetRevisions returns 2501 ---
When a previous upload attempt fails after the file draft is created but
before blocks are committed, a broken draft remains. On the next attempt
the draft is found (2500 "file already exists"), and GetRevisions is called
to decide what to do with it. However, broken drafts return 422/2501 from
the /revisions endpoint, causing handleRevisionConflict to return an error
immediately — even when ReplaceExistingDraft=true.
Fix: if GetRevisions fails AND ReplaceExistingDraft is set AND the link is
in draft state, treat it as a broken draft and delete the link so the caller
can retry from scratch.
--- Bug 2: block uploads missing required Verifier.Token ---
Proton's storage backend now requires a Verifier.Token per block in the
POST /drive/blocks request. Without it, the storage server rejects block
uploads with HTTP 422 / Code=200501 "Operation failed: Please retry".
The token is computed by fetching a VerificationCode for the revision via:
GET /drive/v2/volumes/{volumeID}/links/{linkID}/revisions/{revisionID}/verification
then XOR-ing it with the leading bytes of each block's ciphertext (algorithm
sourced from the official Proton Drive JS SDK in ProtonDriveApps/sdk).
Also bumps go-proton-api to v1.0.1-0.20260218123427-1a63a293e3a2 which
updates the default API host from mail.proton.me/api to drive-api.proton.me.
Note: the JS SDK performs an additional client-side decryption check before
computing the XOR token (to detect bit-flips / bad hardware). That step is
not implemented here; the server-side manifest signature still provides
end-to-end integrity verification. A future improvement could add it.
This fix was identified and generated with Claude Code (AI assistant) by a
non-programmer user (GitHub: lmwashere). It has not been independently
reviewed by a Go or cryptography expert. Expert review before merging is
strongly recommended.
Reproducer: rclone copy <file> proton: --verbose
Expected: upload succeeds
Actual: 422 POST fra-storage.proton.me/storage/blocks (Code=200501)
followed by 422 GET .../revisions (Code=2501) on retry
This fixes Code 2000 errors during move/rename operations. Changes: - Add ReEncryptPassphrase function: re-encrypts node passphrase to new parent keyring while reusing the original symmetric session key - Add ReEncryptName function: re-encrypts node name for new parent keyring while reusing the original session key and re-signing with current addrKR - Add decryptSessionKey helper with fallback chain - Update moveLink to use new functions - Set ContentHash = nil explicitly for file moves - Only include NodePassphraseSignature for anonymous nodes (KeyAuthor == nil) Test results: - FsMove: PASS (was failing with Code 2000) - FsDirMove: PASS (was failing with Code 2000) - All other tests: PASS
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
Implement session key reuse for move/rename operations to fix Code 2000 errors.
Changes
ReEncryptPassphrasefunction: re-encrypts node passphrase to new parent keyring while reusing the original symmetric session keyReEncryptNamefunction: re-encrypts node name for new parent keyring while reusing the original session key and re-signing with current addrKRdecryptSessionKeyhelper with fallback chainmoveLinkto use new functionsContentHash = nilexplicitly for file movesNodePassphraseSignaturefor anonymous nodes (KeyAuthor == nil)Why
Code 2000 ("maybe outdated app") errors during move/rename are caused by:
This fix addresses both issues.
Test Results
Requires: rclone/go-proton-api#4