11package proton_api_bridge
22
33import (
4+ "bytes"
45 "crypto/sha256"
56 "encoding/base64"
67 "io"
78
8- "github.com/ProtonMail/gopenpgp/v2/crypto "
9- "github.com/ProtonMail/gopenpgp/v2/helper "
9+ "github.com/ProtonMail/gopenpgp/v3/armor "
10+ "github.com/ProtonMail/gopenpgp/v3/crypto "
1011)
1112
1213func generatePassphrase () (string , error ) {
@@ -19,44 +20,72 @@ func generatePassphrase() (string, error) {
1920 return tokenBase64 , nil
2021}
2122
23+ // generateLockedKey is the v3-equivalent of v2 helper.GenerateKey: it generates
24+ // a new curve25519 key with the given identity, locks it with the passphrase,
25+ // and returns the armored locked key.
26+ func generateLockedKey (name , email string , passphrase []byte ) (string , error ) {
27+ pgp := crypto .PGP ()
28+ key , err := pgp .KeyGeneration ().AddUserId (name , email ).New ().GenerateKey ()
29+ if err != nil {
30+ return "" , err
31+ }
32+ defer key .ClearPrivateParams ()
33+
34+ locked , err := pgp .LockKey (key , passphrase )
35+ if err != nil {
36+ return "" , err
37+ }
38+ return locked .Armor ()
39+ }
40+
2241func generateCryptoKey () (string , string , error ) {
2342 passphrase , err := generatePassphrase ()
2443 if err != nil {
2544 return "" , "" , err
2645 }
2746
28- // all hardcoded values from iOS drive
29- key , err := helper .GenerateKey ("Drive key" , "noreply@protonmail.com" , []byte (passphrase ), "x25519" , 0 )
47+ // "Drive key" / "noreply@protonmail.com" are the hardcoded identity used by
48+ // the iOS Drive client; v3's default profile produces a curve25519 key,
49+ // which is what the v2 helper produced for keyType "x25519".
50+ key , err := generateLockedKey ("Drive key" , "noreply@protonmail.com" , []byte (passphrase ))
3051 if err != nil {
3152 return "" , "" , err
3253 }
3354
3455 return passphrase , key , nil
3556}
3657
37- // taken from Proton Go API Backend
58+ // encryptWithSignature encrypts b to kr and signs it with addrKR, returning the
59+ // armored ciphertext and armored detached signature.
3860func encryptWithSignature (kr , addrKR * crypto.KeyRing , b []byte ) (string , string , error ) {
39- enc , err := kr .Encrypt (crypto .NewPlainMessage (b ), nil )
61+ pgp := crypto .PGP ()
62+
63+ encHandle , err := pgp .Encryption ().Recipients (kr ).New ()
64+ if err != nil {
65+ return "" , "" , err
66+ }
67+
68+ enc , err := encHandle .Encrypt (b )
4069 if err != nil {
4170 return "" , "" , err
4271 }
4372
44- encArm , err := enc .GetArmored ()
73+ encArm , err := enc .Armor ()
4574 if err != nil {
4675 return "" , "" , err
4776 }
4877
49- sig , err := addrKR . SignDetached ( crypto . NewPlainMessage ( b ) )
78+ signHandle , err := pgp . Sign (). SigningKeys ( addrKR ). Detached (). New ( )
5079 if err != nil {
5180 return "" , "" , err
5281 }
5382
54- sigArm , err := sig . GetArmored ( )
83+ sigArm , err := signHandle . Sign ( b , crypto . Armor )
5584 if err != nil {
5685 return "" , "" , err
5786 }
5887
59- return encArm , sigArm , nil
88+ return encArm , string ( sigArm ) , nil
6089}
6190
6291func generateNodeKeys (kr , addrKR * crypto.KeyRing ) (string , string , string , error ) {
@@ -74,52 +103,79 @@ func generateNodeKeys(kr, addrKR *crypto.KeyRing) (string, string, string, error
74103}
75104
76105func reencryptKeyPacket (srcKR , dstKR , addrKR * crypto.KeyRing , passphrase string ) (string , error ) {
77- oldSplitMessage , err := crypto .NewPGPSplitMessageFromArmored (passphrase )
106+ pgp := crypto .PGP ()
107+
108+ oldMessage , err := crypto .NewPGPMessageFromArmored (passphrase )
78109 if err != nil {
79110 return "" , err
80111 }
81112
82- sessionKey , err := srcKR . DecryptSessionKey ( oldSplitMessage . KeyPacket )
113+ srcDec , err := pgp . Decryption (). DecryptionKeys ( srcKR ). New ( )
83114 if err != nil {
84115 return "" , err
85116 }
86117
87- newKeyPacket , err := dstKR . EncryptSessionKey ( sessionKey )
118+ sessionKey , err := srcDec . DecryptSessionKey ( oldMessage . BinaryKeyPacket () )
88119 if err != nil {
89120 return "" , err
90121 }
91122
92- newSplitMessage := crypto .NewPGPSplitMessage (newKeyPacket , oldSplitMessage .DataPacket )
123+ dstEnc , err := pgp .Encryption ().Recipients (dstKR ).New ()
124+ if err != nil {
125+ return "" , err
126+ }
127+
128+ newKeyPacket , err := dstEnc .EncryptSessionKey (sessionKey )
129+ if err != nil {
130+ return "" , err
131+ }
93132
94- return newSplitMessage .GetArmored ()
133+ newSplitMessage := crypto .NewPGPSplitMessage (newKeyPacket , oldMessage .BinaryDataPacket ())
134+ return newSplitMessage .Armor ()
95135}
96136
97137func getKeyRing (kr , addrKR * crypto.KeyRing , key , passphrase , passphraseSignature string ) (* crypto.KeyRing , error ) {
138+ pgp := crypto .PGP ()
139+
98140 enc , err := crypto .NewPGPMessageFromArmored (passphrase )
99141 if err != nil {
100142 return nil , err
101143 }
102144
103- dec , err := kr . Decrypt ( enc , nil , crypto . GetUnixTime () )
145+ decHandle , err := pgp . Decryption (). DecryptionKeys ( kr ). New ( )
104146 if err != nil {
105147 return nil , err
106148 }
107149
108- sig , err := crypto . NewPGPSignatureFromArmored ( passphraseSignature )
150+ decResult , err := decHandle . Decrypt ( enc . Bytes (), crypto . Bytes )
109151 if err != nil {
110152 return nil , err
111153 }
154+ dec := decResult .Bytes ()
112155
113- if err := addrKR .VerifyDetached (dec , sig , crypto .GetUnixTime ()); err != nil {
156+ sig , err := armor .Unarmor (passphraseSignature )
157+ if err != nil {
114158 return nil , err
115159 }
116160
161+ verifyHandle , err := pgp .Verify ().VerificationKeys (addrKR ).New ()
162+ if err != nil {
163+ return nil , err
164+ }
165+ verifyResult , err := verifyHandle .VerifyDetached (dec , sig , crypto .Bytes )
166+ if err != nil {
167+ return nil , err
168+ }
169+ if sigErr := verifyResult .SignatureError (); sigErr != nil {
170+ return nil , sigErr
171+ }
172+
117173 lockedKey , err := crypto .NewKeyFromArmored (key )
118174 if err != nil {
119175 return nil , err
120176 }
121177
122- unlockedKey , err := lockedKey .Unlock (dec . GetBinary () )
178+ unlockedKey , err := lockedKey .Unlock (dec )
123179 if err != nil {
124180 return nil , err
125181 }
@@ -133,33 +189,48 @@ func decryptBlockIntoBuffer(sessionKey *crypto.SessionKey, addrKR, nodeKR *crypt
133189 return err
134190 }
135191
136- plainMessage , err := sessionKey . Decrypt ( data )
192+ skDec , err := crypto . PGP (). Decryption (). SessionKey ( sessionKey ). New ( )
137193 if err != nil {
138194 return err
139195 }
140-
141- encSignatureArm , err := crypto .NewPGPMessageFromArmored (encSignature )
196+ skResult , err := skDec .Decrypt (data , crypto .Bytes )
142197 if err != nil {
143198 return err
144199 }
200+ plain := skResult .Bytes ()
145201
146- err = addrKR . VerifyDetachedEncrypted ( plainMessage , encSignatureArm , nodeKR , crypto .GetUnixTime () )
202+ encSignatureMsg , err := crypto .NewPGPMessageFromArmored ( encSignature )
147203 if err != nil {
148204 return err
149205 }
150206
151- _ , err = buffer .ReadFrom (plainMessage .NewReader ())
207+ // v2 used addrKR.VerifyDetachedEncrypted, where the signature itself is
208+ // encrypted to nodeKR. v3 expresses this through a Decryption handle with
209+ // PlainDetachedSignature() + DecryptDetached().
210+ decHandle , err := crypto .PGP ().Decryption ().
211+ DecryptionKeys (nodeKR ).
212+ VerificationKeys (addrKR ).
213+ PlainDetachedSignature ().
214+ New ()
152215 if err != nil {
153216 return err
154217 }
218+ verifyResult , err := decHandle .DecryptDetached (plain , encSignatureMsg .Bytes (), crypto .Bytes )
219+ if err != nil {
220+ return err
221+ }
222+ if sigErr := verifyResult .SignatureError (); sigErr != nil {
223+ return sigErr
224+ }
225+
226+ if _ , err := buffer .ReadFrom (bytes .NewReader (plain )); err != nil {
227+ return err
228+ }
155229
156230 h := sha256 .New ()
157231 h .Write (data )
158232 hash := h .Sum (nil )
159233 base64Hash := base64 .StdEncoding .EncodeToString (hash )
160- if err != nil {
161- return err
162- }
163234 if base64Hash != originalHash {
164235 return ErrDownloadedBlockHashVerificationFailed
165236 }
0 commit comments