Also encrypt additional passwords in memory

This commit is contained in:
ycc
2026-02-02 18:28:24 +01:00
parent 7cf212fc76
commit 63a916d18a
2 changed files with 116 additions and 2 deletions

View File

@@ -51,7 +51,7 @@ type Config struct {
// Inner
memoryPassword *memguard.LockedBuffer
additionalPasswords []string
additionalPasswords []*memguard.LockedBuffer
me *Identity
}
@@ -130,5 +130,61 @@ func (c *Config) Clean() {
c.memoryPassword.Destroy()
c.memoryPassword = nil
}
c.additionalPasswords = []string{}
for _, buf := range c.additionalPasswords {
if buf != nil {
buf.Destroy()
}
}
c.additionalPasswords = []*memguard.LockedBuffer{}
}
// AddAdditionalPassword securely stores an additional password in protected memory
func (c *Config) AddAdditionalPassword(password string) {
buf := memguard.NewBufferFromBytes([]byte(password))
c.additionalPasswords = append(c.additionalPasswords, buf)
}
// GetAdditionalPasswords returns all additional passwords as strings
func (c *Config) GetAdditionalPasswords() ([]string, error) {
passwords := make([]string, 0, len(c.additionalPasswords))
for _, buf := range c.additionalPasswords {
if buf == nil {
continue
}
passwords = append(passwords, string(buf.Bytes()))
}
return passwords, nil
}
// GetAdditionalPasswordAt returns the password at the specified index
func (c *Config) GetAdditionalPasswordAt(index int) (string, error) {
if index < 0 || index >= len(c.additionalPasswords) {
return "", errors.New("index out of range")
}
if c.additionalPasswords[index] == nil {
return "", errors.New("password at index is nil")
}
return string(c.additionalPasswords[index].Bytes()), nil
}
// RemoveAdditionalPasswordAt removes and destroys the password at the specified index
func (c *Config) RemoveAdditionalPasswordAt(index int) error {
if index < 0 || index >= len(c.additionalPasswords) {
return errors.New("index out of range")
}
if c.additionalPasswords[index] != nil {
c.additionalPasswords[index].Destroy()
}
c.additionalPasswords = append(c.additionalPasswords[:index], c.additionalPasswords[index+1:]...)
return nil
}
// ClearAdditionalPasswords removes and destroys all additional passwords
func (c *Config) ClearAdditionalPasswords() {
for _, buf := range c.additionalPasswords {
if buf != nil {
buf.Destroy()
}
}
c.additionalPasswords = []*memguard.LockedBuffer{}
}

View File

@@ -21,3 +21,61 @@ func TestConfigLoad(t *testing.T) {
_ = GetConfig().Load("test.cfg")
println(GetConfig().Chunksize)
}
func TestAdditionalPasswords(t *testing.T) {
c := GetConfig()
c.ClearAdditionalPasswords()
// Test adding passwords
c.AddAdditionalPassword("password1")
c.AddAdditionalPassword("password2")
c.AddAdditionalPassword("password3")
// Test getting all passwords
passwords, err := c.GetAdditionalPasswords()
if err != nil {
t.Fatalf("Failed to get passwords: %v", err)
}
if len(passwords) != 3 {
t.Fatalf("Expected 3 passwords, got %d", len(passwords))
}
if passwords[0] != "password1" || passwords[1] != "password2" || passwords[2] != "password3" {
t.Fatalf("Password values don't match expected")
}
// Test getting password at index
pass, err := c.GetAdditionalPasswordAt(1)
if err != nil {
t.Fatalf("Failed to get password at index 1: %v", err)
}
if pass != "password2" {
t.Fatalf("Expected 'password2', got '%s'", pass)
}
// Test removing password at index
err = c.RemoveAdditionalPasswordAt(1)
if err != nil {
t.Fatalf("Failed to remove password: %v", err)
}
passwords, err = c.GetAdditionalPasswords()
if err != nil {
t.Fatalf("Failed to get passwords after removal: %v", err)
}
if len(passwords) != 2 {
t.Fatalf("Expected 2 passwords after removal, got %d", len(passwords))
}
if passwords[0] != "password1" || passwords[1] != "password3" {
t.Fatalf("Password values don't match expected after removal")
}
// Test clearing all passwords
c.ClearAdditionalPasswords()
passwords, err = c.GetAdditionalPasswords()
if err != nil {
t.Fatalf("Failed to get passwords after clear: %v", err)
}
if len(passwords) != 0 {
t.Fatalf("Expected 0 passwords after clear, got %d", len(passwords))
}
}