Delete the keychain item or Secure Enclave key of a failed unlocker add (closes #89)
check / check (push) Failing after 2s
check / check (push) Failing after 2s
A Secure Enclave unlocker add gets the long-term key before it creates the Secure Enclave key, so a wrong passphrase creates none, and deletes the key if a later step fails. macse.CreateKey finds the new key's hash right after sc_auth creates it, failing with an error naming the label if it cannot, and deletes the key if getting its public key then fails. A keychain unlocker add writes all of the unlocker's files before it stores the keychain item, and deletes the item if moving the unlocker into place then fails. A failure to delete is reported along with the original error. The Objective-C and macse_darwin.go were only read, never compiled or run; the new tests run only on a Mac. Model: opus-5-5
This commit was merged in pull request #106.
This commit is contained in:
@@ -4,10 +4,13 @@ package secret
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"github.com/awnumar/memguard"
|
||||
"github.com/spf13/afero"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
@@ -185,3 +188,27 @@ func TestDeleteNonExistentKeychainItem(t *testing.T) {
|
||||
assert.NoError(t, err,
|
||||
"Deleting non-existent keychain item should not return an error")
|
||||
}
|
||||
|
||||
// TestWriteKeychainUnlockerFailureDeletesItem makes moving a new keychain
|
||||
// unlocker into place fail after its data is stored in the keychain: the
|
||||
// keychain item must be deleted again.
|
||||
func TestWriteKeychainUnlockerFailureDeletesItem(t *testing.T) {
|
||||
testItemName := "test-secret-keychain-unlocker-cleanup"
|
||||
_ = deleteFromKeychain(testItemName)
|
||||
|
||||
// Moving the unlocker into a read-only directory fails
|
||||
unlockersDir := filepath.Join(t.TempDir(), "unlockers.d")
|
||||
require.NoError(t, os.Mkdir(unlockersDir, 0o500))
|
||||
|
||||
testBuffer := memguard.NewBufferFromBytes([]byte("test-keychain-data"))
|
||||
defer testBuffer.Destroy()
|
||||
|
||||
_, err := writeKeychainUnlocker(afero.NewOsFs(),
|
||||
filepath.Join(unlockersDir, testItemName), testItemName, "age1test",
|
||||
[]byte("test-priv"), []byte("test-longterm"), testBuffer)
|
||||
require.ErrorIs(t, err, os.ErrPermission,
|
||||
"moving the unlocker into place should fail")
|
||||
|
||||
_, err = retrieveFromKeychain(testItemName)
|
||||
assert.Error(t, err, "keychain item left behind")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user