mirror of
https://github.com/moonD4rk/HackBrowserData.git
synced 2026-06-04 19:48:01 +02:00
refactor: extract master-key code into masterkey package (#604)
This commit is contained in:
+25
-32
@@ -3,39 +3,36 @@ package browser
|
||||
import (
|
||||
"runtime"
|
||||
|
||||
"github.com/moond4rk/hackbrowserdata/crypto/keyretriever"
|
||||
"github.com/moond4rk/hackbrowserdata/log"
|
||||
"github.com/moond4rk/hackbrowserdata/masterkey"
|
||||
)
|
||||
|
||||
// BuildDump exports per-installation master keys. Each Browser is one installation,
|
||||
// so this is a straight one-Vault-per-installation map: ExportKeys is invoked once
|
||||
// per installation. Installations without KeyManager (Firefox/Safari) are skipped.
|
||||
// Partial results (e.g. V10 retrieved, V20 failed) keep the usable tiers rather than
|
||||
// discarding the vault — a Chrome 127+ profile mixes v10 + v20 ciphertexts and a
|
||||
// v20-only failure must not erase a usable v10 key.
|
||||
func BuildDump(browsers []Browser) keyretriever.Dump {
|
||||
dump := keyretriever.NewDump()
|
||||
// BuildDump exports one Vault per installation (Firefox/Safari, lacking KeyManager, are skipped).
|
||||
// Partial results are kept — a Chrome 127+ profile mixes v10+v20, so a v20-only failure must not
|
||||
// discard a usable v10 key.
|
||||
func BuildDump(browsers []Browser) masterkey.Dump {
|
||||
dump := masterkey.NewDump()
|
||||
for _, b := range browsers {
|
||||
km, ok := b.(KeyManager)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
keys, err := km.ExportKeys()
|
||||
mk, err := km.ExportKeys()
|
||||
if err != nil {
|
||||
status := "partial"
|
||||
if !keys.HasAny() {
|
||||
if !mk.HasAny() {
|
||||
status = "failed"
|
||||
}
|
||||
log.Warnf("dump-keys: %s %s: %v", b.BrowserName(), status, err)
|
||||
}
|
||||
if !keys.HasAny() {
|
||||
if !mk.HasAny() {
|
||||
continue
|
||||
}
|
||||
dump.Vaults = append(dump.Vaults, keyretriever.Vault{
|
||||
dump.Vaults = append(dump.Vaults, masterkey.Vault{
|
||||
Browser: b.BrowserName(),
|
||||
UserDataDir: b.UserDataDir(),
|
||||
Profiles: profileNames(b),
|
||||
Keys: keys,
|
||||
Keys: mk,
|
||||
})
|
||||
}
|
||||
return dump
|
||||
@@ -50,21 +47,17 @@ func profileNames(b Browser) []string {
|
||||
return names
|
||||
}
|
||||
|
||||
// ApplyDump installs master keys from dump onto matching installations, replacing
|
||||
// each installation's default platform-native retrievers with StaticProviders
|
||||
// backed by the Dump's bytes. Matching is by (BrowserName, UserDataDir) — the same
|
||||
// key BuildDump emits. When exact match fails (commonly a cross-host path mismatch:
|
||||
// Windows backslash vs POSIX, or a relocated User Data dir via -p), falls back to
|
||||
// the sole vault for that browser name when one exists. Installations without a
|
||||
// matching vault are warned and left untouched; non-KeyManager installations
|
||||
// (Firefox/Safari) are skipped silently.
|
||||
func ApplyDump(browsers []Browser, dump keyretriever.Dump) {
|
||||
// ApplyDump overlays StaticRetrievers from dump onto matching installations (Firefox/Safari skipped).
|
||||
// Match is by (BrowserName, UserDataDir); on miss — commonly a cross-host path mismatch (Windows vs
|
||||
// POSIX, or a relocated dir via -p) — it falls back to the sole vault for that browser name. No match
|
||||
// → warn and leave the platform retrievers in place.
|
||||
func ApplyDump(browsers []Browser, dump masterkey.Dump) {
|
||||
if dump.Host.OS != "" && dump.Host.OS != runtime.GOOS {
|
||||
log.Infof("apply-keys: dump created on %s/%s; current host is %s/%s",
|
||||
dump.Host.OS, dump.Host.Arch, runtime.GOOS, runtime.GOARCH)
|
||||
}
|
||||
vaultIndex := make(map[string]*keyretriever.Vault, len(dump.Vaults))
|
||||
vaultsByBrowser := make(map[string][]*keyretriever.Vault)
|
||||
vaultIndex := make(map[string]*masterkey.Vault, len(dump.Vaults))
|
||||
vaultsByBrowser := make(map[string][]*masterkey.Vault)
|
||||
for i := range dump.Vaults {
|
||||
v := &dump.Vaults[i]
|
||||
vaultIndex[v.Browser+"|"+v.UserDataDir] = v
|
||||
@@ -88,19 +81,19 @@ func ApplyDump(browsers []Browser, dump keyretriever.Dump) {
|
||||
log.Warnf("apply-keys: %s no matching vault in dump", b.BrowserName())
|
||||
continue
|
||||
}
|
||||
km.SetKeyRetrievers(keyretriever.Retrievers{
|
||||
V10: maybeStaticProvider(v.Keys.V10),
|
||||
V11: maybeStaticProvider(v.Keys.V11),
|
||||
V20: maybeStaticProvider(v.Keys.V20),
|
||||
km.SetRetrievers(masterkey.Retrievers{
|
||||
V10: maybeStaticRetriever(v.Keys.V10),
|
||||
V11: maybeStaticRetriever(v.Keys.V11),
|
||||
V20: maybeStaticRetriever(v.Keys.V20),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// maybeStaticProvider wraps non-empty key bytes as a StaticProvider; an empty/nil key returns nil
|
||||
// maybeStaticRetriever wraps non-empty key bytes as a StaticRetriever; an empty/nil key returns nil
|
||||
// to preserve the "tier not applicable" signal NewMasterKeys expects.
|
||||
func maybeStaticProvider(key []byte) keyretriever.KeyRetriever {
|
||||
func maybeStaticRetriever(key []byte) masterkey.Retriever {
|
||||
if len(key) == 0 {
|
||||
return nil
|
||||
}
|
||||
return keyretriever.NewStaticProvider(key)
|
||||
return masterkey.NewStaticRetriever(key)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user