Move CLIkey in KeyHolder

This commit is contained in:
Neeraj Gupta 2023-09-27 14:09:44 +05:30
parent 86385a1a2f
commit 93925b0731
7 changed files with 25 additions and 24 deletions

View file

@ -18,8 +18,7 @@ func main() {
//Host: "http://localhost:8080",
}),
DB: db,
CliKey: secrets.GetOrCreateClISecret(),
KeyHolder: secrets.NewKeyHolder(),
KeyHolder: secrets.NewKeyHolder(secrets.GetOrCreateClISecret()),
}
err = ctrl.Init()
if err != nil {

View file

@ -72,7 +72,6 @@ func (c *ClICtrl) AddAccount(cxt context.Context) {
func (c *ClICtrl) storeAccount(_ context.Context, email string, userID int64, app api.App, secretInfo *model.AccSecretInfo) error {
// get password
secret := c.CliKey
err := c.DB.Update(func(tx *bolt.Tx) error {
b, err := tx.CreateBucketIfNotExists([]byte(AccBucket))
if err != nil {
@ -81,9 +80,9 @@ func (c *ClICtrl) storeAccount(_ context.Context, email string, userID int64, ap
accInfo := model.Account{
Email: email,
UserID: userID,
MasterKey: *model.MakeEncString(secretInfo.MasterKey, secret),
SecretKey: *model.MakeEncString(secretInfo.SecretKey, secret),
Token: *model.MakeEncString(secretInfo.Token, secret),
MasterKey: *model.MakeEncString(secretInfo.MasterKey, c.KeyHolder.DeviceKey),
SecretKey: *model.MakeEncString(secretInfo.SecretKey, c.KeyHolder.DeviceKey),
Token: *model.MakeEncString(secretInfo.Token, c.KeyHolder.DeviceKey),
App: app,
PublicKey: encoding.EncodeBase64(secretInfo.PublicKey),
}

View file

@ -8,10 +8,8 @@ import (
)
type ClICtrl struct {
Client *api.Client
DB *bolt.DB
// CliKey is the key used to encrypt/decrypt sensitive data stored in the database
CliKey []byte
Client *api.Client
DB *bolt.DB
KeyHolder *secrets.KeyHolder
}

View file

@ -4,6 +4,7 @@ import (
"cli-go/internal/api"
eCrypto "cli-go/internal/crypto"
"cli-go/pkg/model"
"cli-go/pkg/secrets"
"cli-go/utils/encoding"
"context"
"encoding/json"
@ -11,7 +12,7 @@ import (
"log"
)
func (c *ClICtrl) mapCollectionToAlbum(ctx context.Context, collection api.Collection) (*model.RemoteAlbum, error) {
func (c *ClICtrl) mapCollectionToAlbum(ctx context.Context, collection api.Collection, holder *secrets.KeyHolder) (*model.RemoteAlbum, error) {
var album model.RemoteAlbum
userID := ctx.Value("user_id").(int64)
album.OwnerID = collection.Owner.ID
@ -19,11 +20,11 @@ func (c *ClICtrl) mapCollectionToAlbum(ctx context.Context, collection api.Colle
album.IsShared = collection.Owner.ID != userID
album.LastUpdatedAt = collection.UpdationTime
album.IsDeleted = collection.IsDeleted
collectionKey, err := c.KeyHolder.GetCollectionKey(ctx, collection)
collectionKey, err := holder.GetCollectionKey(ctx, collection)
if err != nil {
return nil, err
}
album.AlbumKey = *model.MakeEncString(collectionKey, c.CliKey)
album.AlbumKey = *model.MakeEncString(collectionKey, holder.DeviceKey)
var name string
if collection.EncryptedName != "" {
decrName, err := eCrypto.SecretBoxOpenBase64(collection.EncryptedName, collection.NameDecryptionNonce, collectionKey)
@ -69,11 +70,11 @@ func (c *ClICtrl) mapCollectionToAlbum(ctx context.Context, collection api.Colle
return &album, nil
}
func (c *ClICtrl) mapApiFileToPhotoFile(ctx context.Context, album model.RemoteAlbum, file api.File) (*model.RemoteFile, error) {
func (c *ClICtrl) mapApiFileToPhotoFile(ctx context.Context, album model.RemoteAlbum, file api.File, holder *secrets.KeyHolder) (*model.RemoteFile, error) {
if file.IsDeleted {
return nil, errors.New("file is deleted")
}
albumKey := album.AlbumKey.MustDecrypt(c.CliKey)
albumKey := album.AlbumKey.MustDecrypt(holder.DeviceKey)
fileKey, err := eCrypto.SecretBoxOpen(
encoding.DecodeBase64(file.EncryptedKey),
encoding.DecodeBase64(file.KeyDecryptionNonce),
@ -84,7 +85,7 @@ func (c *ClICtrl) mapApiFileToPhotoFile(ctx context.Context, album model.RemoteA
var photoFile model.RemoteFile
photoFile.ID = file.ID
photoFile.LastUpdateTime = file.UpdationTime
photoFile.Key = *model.MakeEncString(fileKey, c.CliKey)
photoFile.Key = *model.MakeEncString(fileKey, holder.DeviceKey)
photoFile.FileNonce = file.File.DecryptionHeader
photoFile.ThumbnailNonce = file.Thumbnail.DecryptionHeader
photoFile.OwnerID = file.OwnerID

View file

@ -25,7 +25,7 @@ func (c *ClICtrl) fetchRemoteCollections(ctx context.Context) error {
if lastSyncTime == 0 && collection.IsDeleted {
continue
}
album, mapErr := c.mapCollectionToAlbum(ctx, collection)
album, mapErr := c.mapCollectionToAlbum(ctx, collection, c.KeyHolder)
if mapErr != nil {
return mapErr
}
@ -84,7 +84,7 @@ func (c *ClICtrl) fetchRemoteFiles(ctx context.Context) error {
// on first sync, no need to sync delete markers
continue
}
photoFile, err := c.mapApiFileToPhotoFile(ctx, album, file)
photoFile, err := c.mapApiFileToPhotoFile(ctx, album, file, c.KeyHolder)
if err != nil {
return err
}

View file

@ -10,14 +10,18 @@ import (
)
type KeyHolder struct {
// DeviceKey is the key used to encrypt/decrypt the data while storing sensitive
// information on the disk. Usually, it should be stored in OS Keychain.
DeviceKey []byte
AccountSecrets map[string]*model.AccSecretInfo
CollectionKeys map[string][]byte
}
func NewKeyHolder() *KeyHolder {
func NewKeyHolder(deviceKey []byte) *KeyHolder {
return &KeyHolder{
AccountSecrets: make(map[string]*model.AccSecretInfo),
CollectionKeys: make(map[string][]byte),
DeviceKey: deviceKey,
}
}
@ -25,10 +29,10 @@ func NewKeyHolder() *KeyHolder {
// It decrypts the token key, master key, and secret key using the CLI key.
// The decrypted keys and the decoded public key are stored in the AccountSecrets map using the account key as the map key.
// It returns the account secret information or an error if the decryption fails.
func (k *KeyHolder) LoadSecrets(account model.Account, cliKey []byte) (*model.AccSecretInfo, error) {
tokenKey := account.Token.MustDecrypt(cliKey)
masterKey := account.MasterKey.MustDecrypt(cliKey)
secretKey := account.SecretKey.MustDecrypt(cliKey)
func (k *KeyHolder) LoadSecrets(account model.Account) (*model.AccSecretInfo, error) {
tokenKey := account.Token.MustDecrypt(k.DeviceKey)
masterKey := account.MasterKey.MustDecrypt(k.DeviceKey)
secretKey := account.SecretKey.MustDecrypt(k.DeviceKey)
k.AccountSecrets[account.AccountKey()] = &model.AccSecretInfo{
Token: tokenKey,
MasterKey: masterKey,

View file

@ -34,7 +34,7 @@ func (c *ClICtrl) StartSync() error {
}
func (c *ClICtrl) SyncAccount(account model.Account) error {
secretInfo, err := c.KeyHolder.LoadSecrets(account, c.CliKey)
secretInfo, err := c.KeyHolder.LoadSecrets(account)
if err != nil {
return err
}