Store both masterKey and secretKey
This commit is contained in:
parent
b4f0994a34
commit
652cf53e32
|
@ -54,12 +54,12 @@ func (c *ClICtrl) AddAccount(cxt context.Context) {
|
|||
if authResponse.EncryptedToken == "" || authResponse.KeyAttributes == nil {
|
||||
panic("no encrypted token or keyAttributes")
|
||||
}
|
||||
masterKey, token, decErr := c.decryptMasterKeyAndToken(cxt, authResponse, keyEncKey)
|
||||
secretInfo, decErr := c.decryptMasterKeyAndToken(cxt, authResponse, keyEncKey)
|
||||
if decErr != nil {
|
||||
flowErr = decErr
|
||||
return
|
||||
}
|
||||
err := c.storeAccount(cxt, email, authResponse.ID, app, masterKey, token)
|
||||
err := c.storeAccount(cxt, email, authResponse.ID, app, secretInfo)
|
||||
if err != nil {
|
||||
flowErr = err
|
||||
return
|
||||
|
@ -68,7 +68,7 @@ func (c *ClICtrl) AddAccount(cxt context.Context) {
|
|||
}
|
||||
}
|
||||
|
||||
func (c *ClICtrl) storeAccount(_ context.Context, email string, userID int64, app api.App, masterKey, token []byte) error {
|
||||
func (c *ClICtrl) storeAccount(_ context.Context, email string, userID int64, app api.App, secretInfo *accSecretInfo) error {
|
||||
// get password
|
||||
secret := GetOrCreateClISecret()
|
||||
err := c.DB.Update(func(tx *bolt.Tx) error {
|
||||
|
@ -79,8 +79,9 @@ func (c *ClICtrl) storeAccount(_ context.Context, email string, userID int64, ap
|
|||
accInfo := model.Account{
|
||||
Email: email,
|
||||
UserID: userID,
|
||||
MasterKey: *model.MakeEncString(string(masterKey), secret),
|
||||
Token: *model.MakeEncString(string(token), secret),
|
||||
MasterKey: *model.MakeEncString(string(secretInfo.MasterKey), secret),
|
||||
Token: *model.MakeEncString(string(secretInfo.Token), secret),
|
||||
SecretKey: *model.MakeEncString(string(secretInfo.SecretKey), secret),
|
||||
App: app,
|
||||
}
|
||||
accInfoBytes, err := json.Marshal(accInfo)
|
||||
|
|
|
@ -10,6 +10,7 @@ type Account struct {
|
|||
UserID int64 `json:"userID" binding:"required"`
|
||||
App api.App `json:"app" binding:"required"`
|
||||
MasterKey EncString `json:"masterKey" binding:"required"`
|
||||
SecretKey EncString `json:"secretKey" binding:"required"`
|
||||
Token EncString `json:"token" binding:"required"`
|
||||
}
|
||||
|
||||
|
|
|
@ -17,15 +17,15 @@ func MakeEncString(plainText string, key []byte) *EncString {
|
|||
log.Fatalf("failed to encrypt %s", err)
|
||||
}
|
||||
return &EncString{
|
||||
CipherText: utils.BytesToBase64(cipher),
|
||||
Nonce: utils.BytesToBase64(nonce),
|
||||
CipherText: utils.EncodeBase64(cipher),
|
||||
Nonce: utils.EncodeBase64(nonce),
|
||||
}
|
||||
}
|
||||
|
||||
func (e *EncString) MustDecrypt(key []byte) string {
|
||||
plainBytes, err := crypto.DecryptChaCha20poly1305(utils.Base64DecodeString(e.CipherText), key, utils.Base64DecodeString(e.Nonce))
|
||||
plainBytes, err := crypto.DecryptChaCha20poly1305(utils.DecodeBase64(e.CipherText), key, utils.DecodeBase64(e.Nonce))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return utils.BytesToBase64(plainBytes)
|
||||
return utils.EncodeBase64(plainBytes)
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ func (c *ClICtrl) SyncAccount(account model.Account) error {
|
|||
return err
|
||||
}
|
||||
token := account.Token.MustDecrypt(cliSecret)
|
||||
urlEncodedToken := base64.URLEncoding.EncodeToString(utils.Base64DecodeString(token))
|
||||
urlEncodedToken := base64.URLEncoding.EncodeToString(utils.DecodeBase64(token))
|
||||
c.Client.AddToken(account.AccountKey(), urlEncodedToken)
|
||||
ctx := c.GetRequestContext(context.Background(), account)
|
||||
return c.syncRemoteCollections(ctx, account)
|
||||
|
|
|
@ -11,6 +11,12 @@ import (
|
|||
"github.com/kong/go-srp"
|
||||
)
|
||||
|
||||
type accSecretInfo struct {
|
||||
MasterKey []byte
|
||||
SecretKey []byte
|
||||
Token []byte
|
||||
}
|
||||
|
||||
func (c *ClICtrl) signInViaPassword(ctx context.Context, email string, srpAttr *api.SRPAttributes) (*api.AuthorizationResponse, []byte, error) {
|
||||
for {
|
||||
// CLI prompt for password
|
||||
|
@ -28,18 +34,18 @@ func (c *ClICtrl) signInViaPassword(ctx context.Context, email string, srpAttr *
|
|||
|
||||
srpParams := srp.GetParams(4096)
|
||||
identify := []byte(srpAttr.SRPUserID.String())
|
||||
salt := utils.Base64DecodeString(srpAttr.SRPSalt)
|
||||
salt := utils.DecodeBase64(srpAttr.SRPSalt)
|
||||
clientSecret := srp.GenKey()
|
||||
srpClient := srp.NewClient(srpParams, salt, identify, loginKey, clientSecret)
|
||||
clientA := srpClient.ComputeA()
|
||||
session, err := c.Client.CreateSRPSession(ctx, srpAttr.SRPUserID, utils.BytesToBase64(clientA))
|
||||
session, err := c.Client.CreateSRPSession(ctx, srpAttr.SRPUserID, utils.EncodeBase64(clientA))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
serverB := session.SRPB
|
||||
srpClient.SetB(utils.Base64DecodeString(serverB))
|
||||
srpClient.SetB(utils.DecodeBase64(serverB))
|
||||
clientM := srpClient.ComputeM1()
|
||||
authResp, err := c.Client.VerifySRPSession(ctx, srpAttr.SRPUserID, session.SessionID, utils.BytesToBase64(clientM))
|
||||
authResp, err := c.Client.VerifySRPSession(ctx, srpAttr.SRPUserID, session.SessionID, utils.EncodeBase64(clientM))
|
||||
if err != nil {
|
||||
log.Printf("failed to verify %v", err)
|
||||
continue
|
||||
|
@ -55,60 +61,66 @@ func (c *ClICtrl) decryptMasterKeyAndToken(
|
|||
_ context.Context,
|
||||
authResp *api.AuthorizationResponse,
|
||||
keyEncKey []byte,
|
||||
) (masterKey, token []byte, err error) {
|
||||
) (*accSecretInfo, error) {
|
||||
|
||||
var currentKeyEncKey []byte
|
||||
var masterKey, secretKey, tokenKey []byte
|
||||
var err error
|
||||
for {
|
||||
if keyEncKey == nil {
|
||||
// CLI prompt for password
|
||||
password, flowErr := GetSensitiveField("Enter password")
|
||||
if flowErr != nil {
|
||||
return nil, nil, flowErr
|
||||
return nil, flowErr
|
||||
}
|
||||
fmt.Println("\nPlease wait authenticating...")
|
||||
currentKeyEncKey, err = enteCrypto.DeriveArgonKey(password,
|
||||
authResp.KeyAttributes.KEKSalt, authResp.KeyAttributes.MemLimit, authResp.KeyAttributes.OpsLimit)
|
||||
if err != nil {
|
||||
fmt.Printf("error deriving key encryption key: %v", err)
|
||||
return nil, nil, err
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
currentKeyEncKey = keyEncKey
|
||||
}
|
||||
|
||||
encryptedKey := utils.Base64DecodeString(authResp.KeyAttributes.EncryptedKey)
|
||||
encryptedKeyNonce := utils.Base64DecodeString(authResp.KeyAttributes.KeyDecryptionNonce)
|
||||
encryptedKey := utils.DecodeBase64(authResp.KeyAttributes.EncryptedKey)
|
||||
encryptedKeyNonce := utils.DecodeBase64(authResp.KeyAttributes.KeyDecryptionNonce)
|
||||
key, keyErr := enteCrypto.SecretBoxOpen(encryptedKey, encryptedKeyNonce, currentKeyEncKey)
|
||||
if keyErr != nil {
|
||||
if keyEncKey != nil {
|
||||
fmt.Printf("Failed to get key from keyEncryptionKey %s", keyErr)
|
||||
return nil, nil, keyErr
|
||||
return nil, keyErr
|
||||
} else {
|
||||
fmt.Printf("Incorrect password, error decrypting master key: %v", keyErr)
|
||||
continue
|
||||
}
|
||||
}
|
||||
masterKey, keyErr = enteCrypto.SecretBoxOpen(
|
||||
utils.Base64DecodeString(authResp.KeyAttributes.EncryptedSecretKey),
|
||||
utils.Base64DecodeString(authResp.KeyAttributes.SecretKeyDecryptionNonce),
|
||||
secretKey, keyErr = enteCrypto.SecretBoxOpen(
|
||||
utils.DecodeBase64(authResp.KeyAttributes.EncryptedSecretKey),
|
||||
utils.DecodeBase64(authResp.KeyAttributes.SecretKeyDecryptionNonce),
|
||||
key,
|
||||
)
|
||||
if keyErr != nil {
|
||||
fmt.Printf("error decrypting master key: %v", keyErr)
|
||||
return nil, nil, keyErr
|
||||
return nil, keyErr
|
||||
}
|
||||
token, err = enteCrypto.SealedBoxOpen(
|
||||
utils.Base64DecodeString(authResp.EncryptedToken),
|
||||
utils.Base64DecodeString(authResp.KeyAttributes.PublicKey),
|
||||
masterKey,
|
||||
tokenKey, err = enteCrypto.SealedBoxOpen(
|
||||
utils.DecodeBase64(authResp.EncryptedToken),
|
||||
utils.DecodeBase64(authResp.KeyAttributes.PublicKey),
|
||||
secretKey,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Printf("error decrypting token: %v", err)
|
||||
return nil, nil, err
|
||||
return nil, err
|
||||
}
|
||||
break
|
||||
}
|
||||
return masterKey, token, nil
|
||||
return &accSecretInfo{
|
||||
MasterKey: masterKey,
|
||||
SecretKey: secretKey,
|
||||
Token: tokenKey,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *ClICtrl) validateTOTP(ctx context.Context, authResp *api.AuthorizationResponse) (*api.AuthorizationResponse, error) {
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"encoding/base64"
|
||||
)
|
||||
|
||||
func Base64DecodeString(s string) []byte {
|
||||
func DecodeBase64(s string) []byte {
|
||||
b, err := base64.StdEncoding.DecodeString(s)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
@ -12,6 +12,6 @@ func Base64DecodeString(s string) []byte {
|
|||
return b
|
||||
}
|
||||
|
||||
func BytesToBase64(b []byte) string {
|
||||
func EncodeBase64(b []byte) string {
|
||||
return base64.StdEncoding.EncodeToString(b)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue