mirror of
https://github.com/sonr-io/sonr.git
synced 2026-08-05 02:41:41 +00:00
@@ -0,0 +1,167 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/sonr-io/sonr/crypto/argon2"
|
||||
"github.com/sonr-io/sonr/crypto/mpc"
|
||||
"github.com/sonr-io/sonr/crypto/password"
|
||||
didtypes "github.com/sonr-io/sonr/x/did/types"
|
||||
)
|
||||
|
||||
// CreateVaultForDIDSecure creates a vault with user-provided password
|
||||
func (k Keeper) CreateVaultForDIDSecure(
|
||||
ctx context.Context,
|
||||
did string,
|
||||
owner string,
|
||||
vaultID string,
|
||||
keyID string,
|
||||
userPassword []byte,
|
||||
enclaveData *mpc.EnclaveData,
|
||||
) (*didtypes.CreateVaultResponse, error) {
|
||||
// Validate password strength
|
||||
validator := password.NewValidator(password.DefaultPasswordConfig())
|
||||
if err := validator.Validate(userPassword); err != nil {
|
||||
return nil, fmt.Errorf("password validation failed: %w", err)
|
||||
}
|
||||
|
||||
// Create Argon2id KDF with default secure parameters
|
||||
kdf := argon2.New(argon2.DefaultConfig())
|
||||
|
||||
// Generate secure salt
|
||||
salt, err := kdf.GenerateSalt()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to generate salt: %w", err)
|
||||
}
|
||||
|
||||
// Derive encryption key using Argon2id
|
||||
derivedKey := kdf.DeriveKey(userPassword, salt)
|
||||
|
||||
// Clear password from memory
|
||||
defer password.ZeroBytes(userPassword)
|
||||
|
||||
// Encrypt enclave data with derived key
|
||||
encryptedData, err := k.encryptEnclaveData(enclaveData, derivedKey)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to encrypt vault data: %w", err)
|
||||
}
|
||||
|
||||
// Store vault with encrypted data and salt
|
||||
vaultState, err := k.storeSecureVault(ctx, vaultID, owner, encryptedData, salt)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to store secure vault: %w", err)
|
||||
}
|
||||
|
||||
return &didtypes.CreateVaultResponse{
|
||||
VaultID: vaultState.VaultId,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// UnlockVault unlocks a vault using the user's password
|
||||
func (k Keeper) UnlockVault(
|
||||
ctx context.Context,
|
||||
vaultID string,
|
||||
userPassword []byte,
|
||||
) (*mpc.EnclaveData, error) {
|
||||
// Retrieve vault state with salt
|
||||
vaultState, err := k.getVaultState(ctx, vaultID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to retrieve vault: %w", err)
|
||||
}
|
||||
|
||||
if len(vaultState.Salt) == 0 {
|
||||
return nil, fmt.Errorf("vault salt not found")
|
||||
}
|
||||
|
||||
// Create KDF with same config as creation
|
||||
kdf := argon2.New(argon2.DefaultConfig())
|
||||
|
||||
// Derive key using stored salt
|
||||
derivedKey := kdf.DeriveKey(userPassword, vaultState.Salt)
|
||||
|
||||
// Clear password from memory
|
||||
defer password.ZeroBytes(userPassword)
|
||||
|
||||
// Decrypt enclave data
|
||||
enclaveData, err := k.decryptEnclaveData(vaultState.EncryptedData, derivedKey)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to decrypt vault: invalid password")
|
||||
}
|
||||
|
||||
return enclaveData, nil
|
||||
}
|
||||
|
||||
// encryptEnclaveData encrypts enclave data with AES-GCM
|
||||
func (k Keeper) encryptEnclaveData(data *mpc.EnclaveData, key []byte) ([]byte, error) {
|
||||
// Implementation would use AES-GCM for authenticated encryption
|
||||
// This is a placeholder - actual implementation needs crypto/cipher
|
||||
|
||||
// For now, return a placeholder
|
||||
// In production, this would:
|
||||
// 1. Serialize enclave data to JSON
|
||||
// 2. Create AES-GCM cipher with key
|
||||
// 3. Generate nonce
|
||||
// 4. Encrypt and authenticate data
|
||||
// 5. Return nonce + ciphertext
|
||||
|
||||
return []byte("encrypted_placeholder"), nil
|
||||
}
|
||||
|
||||
// decryptEnclaveData decrypts enclave data
|
||||
func (k Keeper) decryptEnclaveData(encryptedData []byte, key []byte) (*mpc.EnclaveData, error) {
|
||||
// Implementation would use AES-GCM for authenticated decryption
|
||||
// This is a placeholder - actual implementation needs crypto/cipher
|
||||
|
||||
// For now, return a placeholder
|
||||
// In production, this would:
|
||||
// 1. Extract nonce from encrypted data
|
||||
// 2. Create AES-GCM cipher with key
|
||||
// 3. Decrypt and verify authentication
|
||||
// 4. Deserialize JSON to enclave data
|
||||
// 5. Return decrypted enclave data
|
||||
|
||||
return &mpc.EnclaveData{}, nil
|
||||
}
|
||||
|
||||
// storeSecureVault stores encrypted vault data with salt
|
||||
func (k Keeper) storeSecureVault(
|
||||
ctx context.Context,
|
||||
vaultID string,
|
||||
owner string,
|
||||
encryptedData []byte,
|
||||
salt []byte,
|
||||
) (*VaultStateWithSalt, error) {
|
||||
// This would store the vault state with salt in the database
|
||||
// For now, return a placeholder
|
||||
|
||||
vaultState := &VaultStateWithSalt{
|
||||
VaultId: vaultID,
|
||||
Owner: owner,
|
||||
EncryptedData: encryptedData,
|
||||
Salt: salt,
|
||||
}
|
||||
|
||||
// In production: k.OrmDB.VaultStateTable().Insert(ctx, vaultState)
|
||||
|
||||
return vaultState, nil
|
||||
}
|
||||
|
||||
// getVaultState retrieves vault state with salt
|
||||
func (k Keeper) getVaultState(ctx context.Context, vaultID string) (*VaultStateWithSalt, error) {
|
||||
// This would retrieve the vault state from the database
|
||||
// For now, return a placeholder
|
||||
|
||||
return &VaultStateWithSalt{
|
||||
VaultId: vaultID,
|
||||
Salt: []byte("placeholder_salt"),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// VaultStateWithSalt extends vault state with salt storage
|
||||
type VaultStateWithSalt struct {
|
||||
VaultId string
|
||||
Owner string
|
||||
EncryptedData []byte
|
||||
Salt []byte
|
||||
}
|
||||
Reference in New Issue
Block a user