// Package memutil provides utilities for secure memory handling. // These utilities help prevent sensitive data from remaining in memory // after use, protecting against memory dump attacks. package memutil import ( "crypto/subtle" "github.com/awnumar/memguard" sbytes "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/security/securebytes" sstring "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/security/securestring" ) // WipeString overwrites a string's backing array with zeros and clears the string. // Note: This only works if the string variable is the only reference to the data. // For better security, use SecureString instead of plain strings for sensitive data. func WipeString(s *string) { if s == nil || *s == "" { return } // Convert to byte slice and wipe // Note: This creates a copy, but we wipe what we can bytes := []byte(*s) memguard.WipeBytes(bytes) *s = "" } // SecureCompareStrings performs constant-time comparison of two strings. // This prevents timing attacks when comparing secrets. func SecureCompareStrings(a, b string) bool { return subtle.ConstantTimeCompare([]byte(a), []byte(b)) == 1 } // SecureCompareBytes performs constant-time comparison of two byte slices. // If wipeAfter is true, both slices are wiped after comparison. func SecureCompareBytes(a, b []byte, wipeAfter bool) bool { if wipeAfter { defer memguard.WipeBytes(a) defer memguard.WipeBytes(b) } return subtle.ConstantTimeCompare(a, b) == 1 } // WithSecureBytes executes a function with secure byte handling. // The bytes are automatically wiped after the function returns. func WithSecureBytes(data []byte, fn func([]byte) error) error { defer memguard.WipeBytes(data) return fn(data) } // WithSecureString executes a function with secure string handling. // The SecureString is automatically wiped after the function returns. func WithSecureString(str string, fn func(*sstring.SecureString) error) error { secure, err := sstring.NewSecureString(str) if err != nil { return err } defer secure.Wipe() return fn(secure) } // CloneAndWipe creates a copy of data and wipes the original. // Useful when you need to pass data to a function that will store it, // but want to ensure the original is wiped. func CloneAndWipe(data []byte) []byte { if data == nil { return nil } clone := make([]byte, len(data)) copy(clone, data) memguard.WipeBytes(data) return clone } // SecureZero overwrites memory with zeros. // This is a convenience wrapper around memguard.WipeBytes. func SecureZero(data []byte) { memguard.WipeBytes(data) } // WipeSecureString wipes a SecureString if it's not nil. // This is a nil-safe convenience wrapper. func WipeSecureString(s *sstring.SecureString) { if s != nil { s.Wipe() } } // WipeSecureBytes wipes a SecureBytes if it's not nil. // This is a nil-safe convenience wrapper. func WipeSecureBytes(s *sbytes.SecureBytes) { if s != nil { s.Wipe() } }