This commit is contained in:
Neeraj Gupta 2023-09-23 16:15:10 +05:30
parent c5f978d32b
commit 02ff452c09
10 changed files with 89 additions and 77 deletions

View file

@ -1,4 +1,4 @@
package pkg
package internal
import (
"cli-go/internal/api"

View file

@ -4,6 +4,7 @@ import (
"cli-go/cmd"
"cli-go/internal/api"
"cli-go/pkg"
"cli-go/pkg/secrets"
)
func main() {
@ -17,8 +18,8 @@ func main() {
Host: "http://localhost:8080",
}),
DB: db,
CliKey: pkg.GetOrCreateClISecret(),
KeyHolder: pkg.NewKeyHolder(),
CliKey: secrets.GetOrCreateClISecret(),
KeyHolder: secrets.NewKeyHolder(),
}
err = ctrl.Init()
if err != nil {

View file

@ -1,6 +1,7 @@
package pkg
import (
"cli-go/internal"
"cli-go/internal/api"
"cli-go/pkg/model"
"cli-go/utils/encoding"
@ -21,9 +22,9 @@ func (c *ClICtrl) AddAccount(cxt context.Context) {
log.Fatal(flowErr)
}
}()
app := GetAppType()
app := internal.GetAppType()
cxt = context.WithValue(cxt, "app", string(app))
email, flowErr := GetUserInput("Enter email address")
email, flowErr := internal.GetUserInput("Enter email address")
if flowErr != nil {
return
}
@ -69,7 +70,7 @@ func (c *ClICtrl) AddAccount(cxt context.Context) {
}
}
func (c *ClICtrl) storeAccount(_ context.Context, email string, userID int64, app api.App, secretInfo *accSecretInfo) error {
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 {

57
pkg/collections.go Normal file
View file

@ -0,0 +1,57 @@
package pkg
import (
"cli-go/internal/api"
enteCrypto "cli-go/internal/crypto"
"cli-go/pkg/model"
"cli-go/utils/encoding"
"context"
"fmt"
"log"
)
func (c *ClICtrl) syncRemoteCollections(ctx context.Context, info model.Account) error {
collections, err := c.Client.GetCollections(ctx, 0)
if err != nil {
return fmt.Errorf("failed to get collections: %s", err)
}
for _, collection := range collections {
collectionKey, err := c.getCollectionKey(ctx, collection)
if err != nil {
return err
}
name, nameErr := enteCrypto.SecretBoxOpenBase64(collection.EncryptedName, collection.NameDecryptionNonce, collectionKey)
if nameErr != nil {
log.Fatalf("failed to decrypt collection name: %v", nameErr)
}
if collection.Owner.ID != info.UserID {
fmt.Printf("Shared Album %s\n", string(name))
continue
} else {
fmt.Printf("Owned Name %s\n", string(name))
}
}
return nil
}
func (c *ClICtrl) getCollectionKey(ctx context.Context, collection api.Collection) ([]byte, error) {
accSecretInfo := c.KeyHolder.GetAccountSecretInfo(ctx)
userID := ctx.Value("user_id").(int64)
if collection.Owner.ID == userID {
collKey, err := enteCrypto.SecretBoxOpen(
encoding.DecodeBase64(collection.EncryptedKey),
encoding.DecodeBase64(collection.KeyDecryptionNonce),
accSecretInfo.MasterKey)
if err != nil {
log.Fatalf("failed to decrypt collection key %s", err)
}
return collKey, nil
} else {
collKey, err := enteCrypto.SealedBoxOpen(encoding.DecodeBase64(collection.EncryptedKey),
accSecretInfo.PublicKey, accSecretInfo.SecretKey)
if err != nil {
log.Fatalf("failed to decrypt collection key %s", err)
}
return collKey, nil
}
}

View file

@ -2,6 +2,7 @@ package pkg
import (
"cli-go/internal/api"
"cli-go/pkg/secrets"
"fmt"
bolt "go.etcd.io/bbolt"
)
@ -11,7 +12,7 @@ type ClICtrl struct {
DB *bolt.DB
// CliKey is the key used to encrypt/decrypt sensitive data stored in the database
CliKey []byte
KeyHolder *KeyHolder
KeyHolder *secrets.KeyHolder
}
func (c *ClICtrl) Init() error {

View file

@ -23,3 +23,10 @@ func (a *Account) AccountKey() string {
func (a *Account) DataBucket() string {
return fmt.Sprintf("%s-%d-data", a.App, a.UserID)
}
type AccSecretInfo struct {
MasterKey []byte
SecretKey []byte
Token []byte
PublicKey []byte
}

View file

@ -1,10 +1,7 @@
package pkg
import (
"cli-go/internal/api"
enteCrypto "cli-go/internal/crypto"
"cli-go/pkg/model"
"cli-go/utils/encoding"
"context"
"encoding/base64"
"fmt"
@ -51,50 +48,3 @@ func createDataBuckets(db *bolt.DB, account model.Account) error {
return nil
})
}
func (c *ClICtrl) syncRemoteCollections(ctx context.Context, info model.Account) error {
collections, err := c.Client.GetCollections(ctx, 0)
if err != nil {
return fmt.Errorf("failed to get collections: %s", err)
}
for _, collection := range collections {
collectionKey, err := c.getCollectionKey(ctx, collection)
if err != nil {
return err
}
name, nameErr := enteCrypto.SecretBoxOpenBase64(collection.EncryptedName, collection.NameDecryptionNonce, collectionKey)
if nameErr != nil {
log.Fatalf("failed to decrypt collection name: %v", nameErr)
}
if collection.Owner.ID != info.UserID {
fmt.Printf("Shared Album %s\n", string(name))
continue
} else {
fmt.Printf("Owned Name %s\n", string(name))
}
}
return nil
}
func (c *ClICtrl) getCollectionKey(ctx context.Context, collection api.Collection) ([]byte, error) {
accSecretInfo := c.KeyHolder.GetAccountSecretInfo(ctx)
userID := ctx.Value("user_id").(int64)
if collection.Owner.ID == userID {
collKey, err := enteCrypto.SecretBoxOpen(
encoding.DecodeBase64(collection.EncryptedKey),
encoding.DecodeBase64(collection.KeyDecryptionNonce),
accSecretInfo.MasterKey)
if err != nil {
log.Fatalf("failed to decrypt collection key %s", err)
}
return collKey, nil
} else {
collKey, err := enteCrypto.SealedBoxOpen(encoding.DecodeBase64(collection.EncryptedKey),
accSecretInfo.PublicKey, accSecretInfo.SecretKey)
if err != nil {
log.Fatalf("failed to decrypt collection key %s", err)
}
return collKey, nil
}
}

View file

@ -1,4 +1,4 @@
package pkg
package secrets
import (
"cli-go/pkg/model"
@ -7,22 +7,22 @@ import (
)
type KeyHolder struct {
AccountSecrets map[string]*accSecretInfo
AccountSecrets map[string]*model.AccSecretInfo
CollectionKeys map[string][]byte
}
func NewKeyHolder() *KeyHolder {
return &KeyHolder{
AccountSecrets: make(map[string]*accSecretInfo),
AccountSecrets: make(map[string]*model.AccSecretInfo),
CollectionKeys: make(map[string][]byte),
}
}
func (k *KeyHolder) LoadSecrets(account model.Account, cliKey []byte) (*accSecretInfo, error) {
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)
k.AccountSecrets[account.AccountKey()] = &accSecretInfo{
k.AccountSecrets[account.AccountKey()] = &model.AccSecretInfo{
Token: tokenKey,
MasterKey: masterKey,
SecretKey: secretKey,
@ -31,7 +31,7 @@ func (k *KeyHolder) LoadSecrets(account model.Account, cliKey []byte) (*accSecre
return k.AccountSecrets[account.AccountKey()], nil
}
func (k *KeyHolder) GetAccountSecretInfo(ctx context.Context) *accSecretInfo {
func (k *KeyHolder) GetAccountSecretInfo(ctx context.Context) *model.AccSecretInfo {
accountKey := ctx.Value("account_id").(string)
return k.AccountSecrets[accountKey]
}

View file

@ -1,4 +1,4 @@
package pkg
package secrets
import (
"crypto/rand"

View file

@ -1,8 +1,10 @@
package pkg
import (
"cli-go/internal"
"cli-go/internal/api"
enteCrypto "cli-go/internal/crypto"
"cli-go/pkg/model"
"cli-go/utils/encoding"
"context"
"fmt"
@ -11,17 +13,10 @@ import (
"github.com/kong/go-srp"
)
type accSecretInfo struct {
MasterKey []byte
SecretKey []byte
Token []byte
PublicKey []byte
}
func (c *ClICtrl) signInViaPassword(ctx context.Context, email string, srpAttr *api.SRPAttributes) (*api.AuthorizationResponse, []byte, error) {
for {
// CLI prompt for password
password, flowErr := GetSensitiveField("Enter password")
password, flowErr := internal.GetSensitiveField("Enter password")
if flowErr != nil {
return nil, nil, flowErr
}
@ -62,7 +57,7 @@ func (c *ClICtrl) decryptAccSecretInfo(
_ context.Context,
authResp *api.AuthorizationResponse,
keyEncKey []byte,
) (*accSecretInfo, error) {
) (*model.AccSecretInfo, error) {
var currentKeyEncKey []byte
var err error
var masterKey, secretKey, tokenKey []byte
@ -70,7 +65,7 @@ func (c *ClICtrl) decryptAccSecretInfo(
for {
if keyEncKey == nil {
// CLI prompt for password
password, flowErr := GetSensitiveField("Enter password")
password, flowErr := internal.GetSensitiveField("Enter password")
if flowErr != nil {
return nil, flowErr
}
@ -117,7 +112,7 @@ func (c *ClICtrl) decryptAccSecretInfo(
}
break
}
return &accSecretInfo{
return &model.AccSecretInfo{
MasterKey: masterKey,
SecretKey: secretKey,
Token: tokenKey,
@ -131,7 +126,7 @@ func (c *ClICtrl) validateTOTP(ctx context.Context, authResp *api.AuthorizationR
}
for {
// CLI prompt for TOTP
totp, flowErr := GetCode("Enter TOTP", 6)
totp, flowErr := internal.GetCode("Enter TOTP", 6)
if flowErr != nil {
return nil, flowErr
}
@ -151,7 +146,7 @@ func (c *ClICtrl) validateEmail(ctx context.Context, email string) (*api.Authori
}
for {
// CLI prompt for OTP
ott, flowErr := GetCode("Enter OTP", 6)
ott, flowErr := internal.GetCode("Enter OTP", 6)
if flowErr != nil {
return nil, flowErr
}