mirror of
https://github.com/awnumar/memguard.git
synced 2026-02-07 02:09:53 +00:00
77 lines
2 KiB
Go
77 lines
2 KiB
Go
package core
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
|
|
"github.com/awnumar/memcall"
|
|
)
|
|
|
|
/*
|
|
Purge wipes all sensitive data and keys before reinitialising the session with a fresh encryption key and secure values. Subsequent library operations will use these fresh values and the old data is assumed to be practically unrecoverable.
|
|
|
|
The creation of new Enclave objects should wait for this function to return since subsequent Enclave objects will use the newly created key.
|
|
|
|
This function should be called before the program terminates, or else the provided Exit or Panic functions should be used to terminate.
|
|
*/
|
|
func Purge() {
|
|
var opErr error
|
|
|
|
func() {
|
|
// Halt the re-key cycle and prevent new enclaves.
|
|
key.Lock()
|
|
defer key.Unlock()
|
|
|
|
key.initialise()
|
|
|
|
// Get a snapshot of existing Buffers.
|
|
snapshot := buffers.flush()
|
|
|
|
// Destroy them, performing the usual sanity checks.
|
|
for _, b := range snapshot {
|
|
b.Lock()
|
|
defer b.Unlock()
|
|
|
|
if b == key.left || b == key.right || b == key.rand {
|
|
continue
|
|
}
|
|
|
|
if err := b.destroy(); err != nil {
|
|
if opErr == nil {
|
|
opErr = err
|
|
} else {
|
|
opErr = fmt.Errorf("%s; %s", opErr.Error(), err.Error())
|
|
}
|
|
if !b.Mutable() {
|
|
if err := memcall.Protect(b.inner, memcall.ReadWrite()); err != nil {
|
|
// couldn't change it to mutable; we can't wipe it! (could this happen?)
|
|
// not sure what we can do at this point, just warn and move on
|
|
fmt.Fprintf(os.Stderr, "!WARNING: failed to wipe immutable data at address %p", &b.data)
|
|
continue // wipe in subprocess?
|
|
}
|
|
}
|
|
Wipe(b.data)
|
|
}
|
|
}
|
|
}()
|
|
|
|
// If we encountered an error, panic.
|
|
if opErr != nil {
|
|
panic(opErr)
|
|
}
|
|
}
|
|
|
|
/*
|
|
Exit terminates the process with a specified exit code but securely wipes and cleans up sensitive data before doing so.
|
|
*/
|
|
func Exit(c int) {
|
|
key.destroy()
|
|
|
|
snapshot := buffers.copy() // copy ensures the buffers stay in the list until they are destroyed.
|
|
|
|
for _, b := range snapshot {
|
|
b.Destroy()
|
|
}
|
|
|
|
os.Exit(c)
|
|
}
|