mirror of
https://github.com/moonD4rk/HackBrowserData.git
synced 2026-08-09 23:24:23 +02:00
* feat: add crypto/keyretriever package for Chromium master key retrieval * feat: complete keyretriever with gcoredump, chainbreaker, and tests * refactor: replace internal chainbreaker with keychainbreaker v0.1.0 Replace the incomplete internal chainbreaker implementation (~1400 lines of duplicated code) with the external keychainbreaker package, which provides a complete, well-tested keychain parsing library. Changes: - Add github.com/moond4rk/keychainbreaker v0.1.0 dependency - Update gcoredump_darwin.go to use keychainbreaker API (Open/Unlock/GenericPasswords) - Add KeychainPasswordRetriever for password-based keychain unlocking with sync.Once caching across multiple browser queries - Unify DefaultRetriever(keychainPassword string) signature across all platforms - Delete utils/chainbreaker/ (696 lines + test + testdata) - Delete crypto/keyretriever/chainbreaker_darwin.go (696 lines duplicate) - Delete browser/exploit/gcoredump/ (duplicate of keyretriever version) - Update chromium_darwin.go to use keyretriever.DecryptKeychain - Clean up .golangci.yml lint exceptions and .gitignore entries - Use errors.Is() instead of == for context.DeadlineExceeded check * refactor: improve gcoredump exploit code quality and add comments * fix: address Copilot review feedback on keyretriever
70 lines
1.7 KiB
Go
70 lines
1.7 KiB
Go
package keyretriever
|
|
|
|
import (
|
|
"errors"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
type mockRetriever struct {
|
|
key []byte
|
|
err error
|
|
}
|
|
|
|
func (m *mockRetriever) RetrieveKey(_, _ string) ([]byte, error) {
|
|
return m.key, m.err
|
|
}
|
|
|
|
func TestChainRetriever_FirstSuccess(t *testing.T) {
|
|
chain := NewChain(
|
|
&mockRetriever{key: []byte("first-key")},
|
|
&mockRetriever{key: []byte("second-key")},
|
|
)
|
|
key, err := chain.RetrieveKey("Chrome", "")
|
|
require.NoError(t, err)
|
|
assert.Equal(t, []byte("first-key"), key)
|
|
}
|
|
|
|
func TestChainRetriever_FallbackOnError(t *testing.T) {
|
|
chain := NewChain(
|
|
&mockRetriever{err: errors.New("first failed")},
|
|
&mockRetriever{key: []byte("fallback-key")},
|
|
)
|
|
key, err := chain.RetrieveKey("Chrome", "")
|
|
require.NoError(t, err)
|
|
assert.Equal(t, []byte("fallback-key"), key)
|
|
}
|
|
|
|
func TestChainRetriever_AllFail(t *testing.T) {
|
|
chain := NewChain(
|
|
&mockRetriever{err: errors.New("first failed")},
|
|
&mockRetriever{err: errors.New("second failed")},
|
|
)
|
|
key, err := chain.RetrieveKey("Chrome", "")
|
|
assert.Error(t, err)
|
|
assert.Nil(t, key)
|
|
assert.Contains(t, err.Error(), "all retrievers failed")
|
|
assert.Contains(t, err.Error(), "first failed")
|
|
assert.Contains(t, err.Error(), "second failed")
|
|
}
|
|
|
|
func TestChainRetriever_SkipEmptyKey(t *testing.T) {
|
|
// First returns nil key without error — should skip to next
|
|
chain := NewChain(
|
|
&mockRetriever{key: nil, err: nil},
|
|
&mockRetriever{key: []byte("real-key")},
|
|
)
|
|
key, err := chain.RetrieveKey("Chrome", "")
|
|
require.NoError(t, err)
|
|
assert.Equal(t, []byte("real-key"), key)
|
|
}
|
|
|
|
func TestChainRetriever_Empty(t *testing.T) {
|
|
chain := NewChain()
|
|
key, err := chain.RetrieveKey("Chrome", "")
|
|
assert.Error(t, err)
|
|
assert.Nil(t, key)
|
|
}
|