Add Client.Unlock

This commit is contained in:
emersion 2017-08-22 10:36:43 +02:00
parent d964a951a0
commit 959603b0d9
No known key found for this signature in database
GPG Key ID: 0FDE7BE0E88F5E48
2 changed files with 48 additions and 7 deletions

View File

@ -2,9 +2,11 @@ package protonmail
import ( import (
"encoding/base64" "encoding/base64"
"errors"
"net/http" "net/http"
"strings"
"log" "golang.org/x/crypto/openpgp"
) )
type authInfoReq struct { type authInfoReq struct {
@ -80,15 +82,14 @@ const (
) )
type Auth struct { type Auth struct {
AccessToken string
ExpiresIn int ExpiresIn int
TokenType string
Scope string Scope string
UID string `json:"Uid"` UID string `json:"Uid"`
RefreshToken string RefreshToken string
EventID string EventID string
PasswordMode PasswordMode PasswordMode PasswordMode
accessToken string
privateKey string privateKey string
keySalt string keySalt string
} }
@ -96,6 +97,8 @@ type Auth struct {
type authResp struct { type authResp struct {
resp resp
Auth Auth
AccessToken string
TokenType string
ServerProof string ServerProof string
PrivateKey string PrivateKey string
KeySalt string KeySalt string
@ -103,6 +106,7 @@ type authResp struct {
func (resp *authResp) auth() *Auth { func (resp *authResp) auth() *Auth {
auth := &resp.Auth auth := &resp.Auth
auth.accessToken = resp.AccessToken
auth.privateKey = resp.PrivateKey auth.privateKey = resp.PrivateKey
auth.keySalt = resp.KeySalt auth.keySalt = resp.KeySalt
return auth return auth
@ -141,11 +145,42 @@ func (c *Client) Auth(username, password, twoFactorCode string, info *AuthInfo)
return nil, err return nil, err
} }
log.Printf("%+v\n", respData)
if err := proofs.VerifyServerProof(respData.ServerProof); err != nil { if err := proofs.VerifyServerProof(respData.ServerProof); err != nil {
return nil, err return nil, err
} }
return respData.auth(), nil return respData.auth(), nil
} }
func (c *Client) Unlock(auth *Auth, password []byte) (openpgp.EntityList, error) {
if auth.PasswordMode == PasswordSingle {
keySalt, err := base64.StdEncoding.DecodeString(auth.keySalt)
if err != nil {
return nil, err
}
password, err = computeKeyPassword(password, keySalt)
if err != nil {
return nil, err
}
}
keyRing, err := openpgp.ReadArmoredKeyRing(strings.NewReader(auth.privateKey))
if err != nil {
return nil, err
}
if len(keyRing) == 0 {
return nil, errors.New("auth key ring is empty")
}
for _, e := range keyRing {
if err := e.PrivateKey.Decrypt(password); err != nil {
return nil, err
}
}
c.uid = auth.UID
c.accessToken = auth.accessToken
c.keyRing = keyRing
return keyRing, nil
}

View File

@ -7,6 +7,8 @@ import (
"io" "io"
"net/http" "net/http"
"strconv" "strconv"
"golang.org/x/crypto/openpgp"
) )
const Version = 3 const Version = 3
@ -46,6 +48,10 @@ type Client struct {
ClientSecret string ClientSecret string
HTTPClient *http.Client HTTPClient *http.Client
uid string
accessToken string
keyRing openpgp.EntityList
} }
func (c *Client) newRequest(method, path string, body io.Reader) (*http.Request, error) { func (c *Client) newRequest(method, path string, body io.Reader) (*http.Request, error) {