Merge pull request #40 from scelaris/pr2
protonmail: Decrypt private keys for all available addresses.
This commit is contained in:
commit
56ad3283a3
|
@ -4,6 +4,7 @@ import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"errors"
|
"errors"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
@ -193,6 +194,30 @@ func (c *Client) AuthRefresh(expiredAuth *Auth) (*Auth, error) {
|
||||||
return auth, nil
|
return auth, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func unlockKey(e *openpgp.Entity, passphraseBytes []byte) error {
|
||||||
|
var privateKeys []*packet.PrivateKey
|
||||||
|
|
||||||
|
// e.PrivateKey is a signing key
|
||||||
|
if e.PrivateKey != nil {
|
||||||
|
privateKeys = append(privateKeys, e.PrivateKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
// e.Subkeys are encryption keys
|
||||||
|
for _, subkey := range e.Subkeys {
|
||||||
|
if subkey.PrivateKey != nil {
|
||||||
|
privateKeys = append(privateKeys, subkey.PrivateKey)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, priv := range privateKeys {
|
||||||
|
if err := priv.Decrypt(passphraseBytes); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Client) Unlock(auth *Auth, passphrase string) (openpgp.EntityList, error) {
|
func (c *Client) Unlock(auth *Auth, passphrase string) (openpgp.EntityList, error) {
|
||||||
passphraseBytes := []byte(passphrase)
|
passphraseBytes := []byte(passphrase)
|
||||||
if auth.keySalt != "" {
|
if auth.keySalt != "" {
|
||||||
|
@ -218,26 +243,10 @@ func (c *Client) Unlock(auth *Auth, passphrase string) (openpgp.EntityList, erro
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, e := range keyRing {
|
for _, e := range keyRing {
|
||||||
var privateKeys []*packet.PrivateKey
|
if err := unlockKey(e, passphraseBytes); err != nil {
|
||||||
|
|
||||||
// e.PrivateKey is a signing key
|
|
||||||
if e.PrivateKey != nil {
|
|
||||||
privateKeys = append(privateKeys, e.PrivateKey)
|
|
||||||
}
|
|
||||||
|
|
||||||
// e.Subkeys are encryption keys
|
|
||||||
for _, subkey := range e.Subkeys {
|
|
||||||
if subkey.PrivateKey != nil {
|
|
||||||
privateKeys = append(privateKeys, subkey.PrivateKey)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, priv := range privateKeys {
|
|
||||||
if err := priv.Decrypt(passphraseBytes); err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Decrypt access token
|
// Decrypt access token
|
||||||
|
|
||||||
|
@ -260,6 +269,40 @@ func (c *Client) Unlock(auth *Auth, passphrase string) (openpgp.EntityList, erro
|
||||||
c.uid = auth.UID
|
c.uid = auth.UID
|
||||||
c.accessToken = string(accessTokenBytes)
|
c.accessToken = string(accessTokenBytes)
|
||||||
c.keyRing = keyRing
|
c.keyRing = keyRing
|
||||||
|
|
||||||
|
// Unlock additional private keys
|
||||||
|
addrs, err := c.ListAddresses()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, addr := range addrs {
|
||||||
|
for _, key := range addr.Keys {
|
||||||
|
entity, err := key.Entity()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
found := false
|
||||||
|
for _, e := range keyRing {
|
||||||
|
if e.PrimaryKey.KeyIdString() == entity.PrimaryKey.KeyIdString() {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if found {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := unlockKey(entity, passphraseBytes); err != nil {
|
||||||
|
log.Printf("failed to unlock key %v: %v", entity.PrimaryKey.KeyIdString(), err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
keyRing = append(keyRing, entity)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return keyRing, nil
|
return keyRing, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,13 +9,21 @@ import (
|
||||||
"golang.org/x/crypto/openpgp"
|
"golang.org/x/crypto/openpgp"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type PrivateKeyFlags int
|
||||||
|
|
||||||
|
const (
|
||||||
|
PrivateKeyVerify PrivateKeyFlags = 1
|
||||||
|
PrivateKeyEncrypt = 2
|
||||||
|
)
|
||||||
|
|
||||||
type PrivateKey struct {
|
type PrivateKey struct {
|
||||||
ID string
|
ID string
|
||||||
Version int
|
Version int
|
||||||
PublicKey string
|
Flags PrivateKeyFlags
|
||||||
PrivateKey string
|
PrivateKey string
|
||||||
Fingerprint string
|
Fingerprint string
|
||||||
Activation interface{} // TODO
|
Activation interface{} // TODO
|
||||||
|
Primary int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (priv *PrivateKey) Entity() (*openpgp.Entity, error) {
|
func (priv *PrivateKey) Entity() (*openpgp.Entity, error) {
|
||||||
|
|
Loading…
Reference in New Issue