PassAGE/memory.go
fraggle 3552db50c2 Initial commit: PassAGE password manager
- AGE encryption with master password model
- Core commands: init, show, insert, edit, generate, rm, mv, cp, find, grep, ls
- Git integration for version control
- Clipboard support (X11 and Wayland)
- Secure password generation
- Backup and restore functionality
- Comprehensive security features
- Complete documentation
2026-01-11 18:48:01 -04:00

69 lines
1.7 KiB
Go

package main
import (
"crypto/rand"
"unsafe"
)
// SecureBytes wraps a byte slice and provides secure clearing
// Because Go strings are immutable and we can't really clear them, this helps
type SecureBytes struct {
data []byte
}
// NewSecureBytes creates a new SecureBytes from a byte slice
func NewSecureBytes(data []byte) *SecureBytes {
return &SecureBytes{data: data}
}
// Bytes returns the underlying byte slice
func (sb *SecureBytes) Bytes() []byte {
return sb.data
}
// String returns the string representation (use with caution)
// This uses unsafe.Pointer magic - don't look too closely, it works
func (sb *SecureBytes) String() string {
return *(*string)(unsafe.Pointer(&sb.data))
}
// Clear securely zeros the memory
// Overwrites with random junk first (defense in depth), then zeros
// Not perfect (Go GC might move things around), but better than nothing
func (sb *SecureBytes) Clear() {
if sb == nil || sb.data == nil {
return
}
// Fill with random data first - makes memory dumps less useful
rand.Read(sb.data)
// Then zero it out
for i := range sb.data {
sb.data[i] = 0
}
sb.data = nil
}
// ClearBytes securely clears a byte slice
func ClearBytes(data []byte) {
if data == nil {
return
}
// Overwrite with random data first, then zeros
rand.Read(data)
for i := range data {
data[i] = 0
}
}
// ClearString attempts to clear a string (limited effectiveness in Go)
// Go strings are immutable, so this is mostly wishful thinking
// But hey, at least we tried
func ClearString(s *string) {
if s == nil {
return
}
// Best we can do - just set it to empty
// The original memory might still be around somewhere, but GC will get it eventually
*s = ""
}