v0.79.0: escrow upload carries restic_pw_sha256 (SLICE 3 auto-confirm, agent third)
HashResticPassword = sha256 hex over the trimmed password (pinned cross-repo vector). escrowUploadRequest gains restic_pw_sha256,omitempty — set only when a staged password was sealed into the blob. Contract test updated; hub mirrors next. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
This commit is contained in:
@@ -2,7 +2,9 @@ package escrow
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
@@ -53,6 +55,17 @@ func WipeStagedResticPassword() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// HashResticPassword is the CANONICAL hasher for the offsite restic repo password (SLICE 3 hub-verified
|
||||
// escrow auto-confirm): sha256 hex of the TRIMMED password string — exactly the value AttachResticPassword
|
||||
// seals into the blob and the value the controller uses (both sides TrimSpace their file reads, so the
|
||||
// trimmed string is the drift-free convention; pinned by the SAME test vector in felhom-agent and
|
||||
// felhom-controller). The hash of a 256-bit random secret is non-reversible and non-brute-forceable —
|
||||
// safe to store on the hub and serve in report ACKs; the PASSWORD itself is never logged or served.
|
||||
func HashResticPassword(pw string) string {
|
||||
sum := sha256.Sum256([]byte(strings.TrimSpace(pw)))
|
||||
return hex.EncodeToString(sum[:])
|
||||
}
|
||||
|
||||
// AttachResticPassword injects the offsite restic repo password from the staged 0600 file into the bundle
|
||||
// when it exists (fork-4 escrow-create auto-inject). Returns whether it attached. The VALUE is validated
|
||||
// (non-empty) but NEVER logged by callers — log the field NAME only (mirrors AttachWGKey). A missing file
|
||||
|
||||
Reference in New Issue
Block a user