Save key salts after auth
The key salts endpoint can only be accessed right after authentication, it's blocked after auth refresh. Closes: https://github.com/emersion/hydroxide/issues/68
This commit is contained in:
parent
2de4f13dc4
commit
cc03e059b9
|
@ -25,6 +25,7 @@ type CachedAuth struct {
|
||||||
protonmail.Auth
|
protonmail.Auth
|
||||||
LoginPassword string
|
LoginPassword string
|
||||||
MailboxPassword string
|
MailboxPassword string
|
||||||
|
KeySalts map[string][]byte
|
||||||
// TODO: add padding
|
// TODO: add padding
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,7 +132,7 @@ func authenticate(c *protonmail.Client, cachedAuth *CachedAuth, username string)
|
||||||
}
|
}
|
||||||
cachedAuth.Auth = *auth
|
cachedAuth.Auth = *auth
|
||||||
|
|
||||||
return c.Unlock(auth, cachedAuth.MailboxPassword)
|
return c.Unlock(auth, cachedAuth.KeySalts, cachedAuth.MailboxPassword)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ListUsernames() ([]string, error) {
|
func ListUsernames() ([]string, error) {
|
||||||
|
|
|
@ -184,7 +184,12 @@ func main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := c.Unlock(a, mailboxPassword)
|
keySalts, err := c.ListKeySalts()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = c.Unlock(a, keySalts, mailboxPassword)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -195,9 +200,10 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
err = auth.EncryptAndSave(&auth.CachedAuth{
|
err = auth.EncryptAndSave(&auth.CachedAuth{
|
||||||
*a,
|
Auth: *a,
|
||||||
loginPassword,
|
LoginPassword: loginPassword,
|
||||||
mailboxPassword,
|
MailboxPassword: mailboxPassword,
|
||||||
|
KeySalts: keySalts,
|
||||||
}, username, secretKey)
|
}, username, secretKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
|
|
@ -141,7 +141,10 @@ func (c *Client) Auth(username, password, twoFactorCode string, info *AuthInfo)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return respData.auth(), nil
|
auth := respData.auth()
|
||||||
|
c.uid = auth.UID
|
||||||
|
c.accessToken = auth.AccessToken
|
||||||
|
return auth, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type authRefreshReq struct {
|
type authRefreshReq struct {
|
||||||
|
@ -178,7 +181,7 @@ func (c *Client) AuthRefresh(expiredAuth *Auth) (*Auth, error) {
|
||||||
return auth, nil
|
return auth, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) listKeySalts() (map[string][]byte, error) {
|
func (c *Client) ListKeySalts() (map[string][]byte, error) {
|
||||||
req, err := c.newRequest(http.MethodGet, "/keys/salts", nil)
|
req, err := c.newRequest(http.MethodGet, "/keys/salts", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -235,7 +238,7 @@ func unlockKey(e *openpgp.Entity, passphraseBytes []byte) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) Unlock(auth *Auth, passphrase string) (openpgp.EntityList, error) {
|
func (c *Client) Unlock(auth *Auth, keySalts map[string][]byte, passphrase string) (openpgp.EntityList, error) {
|
||||||
c.uid = auth.UID
|
c.uid = auth.UID
|
||||||
c.accessToken = auth.AccessToken
|
c.accessToken = auth.AccessToken
|
||||||
|
|
||||||
|
@ -244,11 +247,6 @@ func (c *Client) Unlock(auth *Auth, passphrase string) (openpgp.EntityList, erro
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
salts, err := c.listKeySalts()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var keyRing openpgp.EntityList
|
var keyRing openpgp.EntityList
|
||||||
for _, addr := range addrs {
|
for _, addr := range addrs {
|
||||||
for _, key := range addr.Keys {
|
for _, key := range addr.Keys {
|
||||||
|
@ -259,7 +257,7 @@ func (c *Client) Unlock(auth *Auth, passphrase string) (openpgp.EntityList, erro
|
||||||
}
|
}
|
||||||
|
|
||||||
passphraseBytes := []byte(passphrase)
|
passphraseBytes := []byte(passphrase)
|
||||||
if keySalt, ok := salts[key.ID]; ok && keySalt != nil {
|
if keySalt, ok := keySalts[key.ID]; ok && keySalt != nil {
|
||||||
passphraseBytes, err = computeKeyPassword(passphraseBytes, keySalt)
|
passphraseBytes, err = computeKeyPassword(passphraseBytes, keySalt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
Loading…
Reference in New Issue