mirror of
https://github.com/henrybear327/Proton-API-Bridge.git
synced 2026-01-06 22:28:37 -05:00
The Proton-API-Bridge should not be attempting to take over, nor re-define, the existing proton-go-api interfaces. This is known has an "unfriendly fork" and increases the overall complexity of maintaining the Proton-API-Bridge. All changes to the proton-go-api should be done as "friendly" as possible, and should be submitted back upstream for inclusion. This improves the functionality of the proton-go-api for more than just 1 project, and it reduces the long-term maintenance required for Proton-API-Bridge. To this end, Proton-API-Bridge should be written to always assume it is using github.com/ProtonMail/proton-go-api and leverage the `replace` operation in go.mod in order to leverage our "friendly fork" of proton-go-api. I.e. the long-term goal should be to _not_ maintain a fork of proton-go-api. > Anything else would be uncivilized.
76 lines
2.1 KiB
Go
76 lines
2.1 KiB
Go
package common
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/ProtonMail/gopenpgp/v2/crypto"
|
|
"github.com/ProtonMail/go-proton-api"
|
|
)
|
|
|
|
/*
|
|
The Proton account keys are organized in the following hierarchy.
|
|
|
|
An account has some users, each of the user will have one or more user keys.
|
|
Each of the user will have some addresses, each of the address will have one or more address keys.
|
|
|
|
A key is encrypted by a passphrase, and the passphrase is encrypted by another key.
|
|
|
|
The address keyrings are encrypted with the primary user keyring at the time.
|
|
|
|
The primary address key is used to create (encrypt) and retrieve (decrypt) data, e.g. shares
|
|
*/
|
|
func getAccountKRs(ctx context.Context, c *proton.Client, keyPass, saltedKeyPass []byte) (*crypto.KeyRing, map[string]*crypto.KeyRing, map[string]proton.Address, []byte, error) {
|
|
/* Code taken and modified from proton-bridge */
|
|
|
|
user, err := c.GetUser(ctx)
|
|
if err != nil {
|
|
return nil, nil, nil, nil, err
|
|
}
|
|
// log.Printf("user %#v", user)
|
|
|
|
addrsArr, err := c.GetAddresses(ctx)
|
|
if err != nil {
|
|
return nil, nil, nil, nil, err
|
|
}
|
|
// log.Printf("addr %#v", addr)
|
|
|
|
if saltedKeyPass == nil {
|
|
if keyPass == nil {
|
|
return nil, nil, nil, nil, ErrKeyPassOrSaltedKeyPassMustBeNotNil
|
|
}
|
|
|
|
/*
|
|
Notes for -> BUG: Access token does not have sufficient scope
|
|
Only within the first x minutes that the user logs in with username and password, the getSalts route will be available to be called!
|
|
*/
|
|
salts, err := c.GetSalts(ctx)
|
|
if err != nil {
|
|
return nil, nil, nil, nil, err
|
|
}
|
|
// log.Printf("salts %#v", salts)
|
|
|
|
saltedKeyPass, err = salts.SaltForKey(keyPass, user.Keys.Primary().ID)
|
|
if err != nil {
|
|
return nil, nil, nil, nil, err
|
|
}
|
|
// log.Printf("saltedKeyPass ok")
|
|
}
|
|
|
|
userKR, addrKRs, err := proton.Unlock(user, addrsArr, saltedKeyPass, nil)
|
|
if err != nil {
|
|
return nil, nil, nil, nil, err
|
|
|
|
} else if userKR.CountDecryptionEntities() == 0 {
|
|
if err != nil {
|
|
return nil, nil, nil, nil, ErrFailedToUnlockUserKeys
|
|
}
|
|
}
|
|
|
|
addrs := make(map[string]proton.Address)
|
|
for _, addr := range addrsArr {
|
|
addrs[addr.Email] = addr
|
|
}
|
|
|
|
return userKR, addrKRs, addrs, saltedKeyPass, nil
|
|
}
|