mirror of
https://github.com/moonD4rk/HackBrowserData.git
synced 2026-05-19 18:58:03 +02:00
60 lines
2.3 KiB
Go
60 lines
2.3 KiB
Go
// Package keyretriever owns the master-key acquisition chain shared by all Chromium variants (Chrome,
|
|
// Edge, Brave, Arc, Opera, Vivaldi, Yandex, …). The chain is built once per process and reused for
|
|
// every profile.
|
|
//
|
|
// Firefox and Safari do not route through this package — Firefox derives its own keys from key4.db via
|
|
// NSS PBE, and Safari reads InternetPassword records directly from login.keychain-db. Each browser
|
|
// package owns its own credential-acquisition strategy; see rfcs/006-key-retrieval-mechanisms.md §7 for
|
|
// the rationale.
|
|
package keyretriever
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/moond4rk/hackbrowserdata/log"
|
|
)
|
|
|
|
// errStorageNotFound is returned when the requested browser storage account is not found in the
|
|
// credential store (keychain, keyring, etc.). Only used on darwin and linux; Windows uses DPAPI which
|
|
// has no storage lookup.
|
|
var errStorageNotFound = errors.New("not found in credential store") //nolint:unused // only used on darwin and linux
|
|
|
|
// Hints bundles inputs for KeyRetriever; each retriever reads only the field that applies to it.
|
|
type Hints struct {
|
|
KeychainLabel string // macOS Keychain account / Linux D-Bus Secret Service label
|
|
WindowsABEKey string // Windows ABE browser key (e.g. "chrome"); "" → ABE not applicable
|
|
LocalStatePath string // path to (temp-copied) Local State JSON; only used on Windows
|
|
}
|
|
|
|
// KeyRetriever retrieves the master encryption key for a Chromium-based browser.
|
|
type KeyRetriever interface {
|
|
RetrieveKey(hints Hints) ([]byte, error)
|
|
}
|
|
|
|
// ChainRetriever tries multiple retrievers in order, returning the first success. Used on macOS
|
|
// (gcoredump → password → security) and Linux (D-Bus → peanuts).
|
|
type ChainRetriever struct {
|
|
retrievers []KeyRetriever
|
|
}
|
|
|
|
// NewChain creates a ChainRetriever that tries each retriever in order.
|
|
func NewChain(retrievers ...KeyRetriever) KeyRetriever {
|
|
return &ChainRetriever{retrievers: retrievers}
|
|
}
|
|
|
|
func (c *ChainRetriever) RetrieveKey(hints Hints) ([]byte, error) {
|
|
var errs []error
|
|
for _, r := range c.retrievers {
|
|
key, err := r.RetrieveKey(hints)
|
|
if err == nil && len(key) > 0 {
|
|
return key, nil
|
|
}
|
|
if err != nil {
|
|
log.Debugf("keyretriever %T failed: %v", r, err)
|
|
errs = append(errs, fmt.Errorf("%T: %w", r, err))
|
|
}
|
|
}
|
|
return nil, fmt.Errorf("all retrievers failed: %w", errors.Join(errs...))
|
|
}
|