Add Secure Enclave unlocker for hardware-backed secret protection
Adds a new "secure-enclave" unlocker type that stores the vault's long-term private key encrypted by a non-exportable P-256 key held in the Secure Enclave hardware. Decryption (ECDH) is performed inside the SE; the key never leaves the hardware. Uses CryptoTokenKit identities created via sc_auth, which allows SE access from unsigned binaries without Apple Developer Program membership. ECIES (X963SHA256 + AES-GCM) handles encryption and decryption through Security.framework. New package internal/macse/ provides the CGo bridge to Security.framework for SE key creation, ECIES encrypt/decrypt, and key deletion. The SE unlocker directly encrypts the vault long-term key (no intermediate age keypair).
This commit is contained in:
@@ -83,6 +83,9 @@ func (v *Vault) GetCurrentUnlocker() (secret.Unlocker, error) {
|
||||
case "keychain":
|
||||
secret.Debug("Creating keychain unlocker instance", "unlocker_type", metadata.Type)
|
||||
unlocker = secret.NewKeychainUnlocker(v.fs, unlockerDir, metadata)
|
||||
case "secure-enclave":
|
||||
secret.Debug("Creating secure enclave unlocker instance", "unlocker_type", metadata.Type)
|
||||
unlocker = secret.NewSecureEnclaveUnlocker(v.fs, unlockerDir, metadata)
|
||||
default:
|
||||
secret.Debug("Unsupported unlocker type", "type", metadata.Type)
|
||||
|
||||
@@ -166,6 +169,8 @@ func (v *Vault) findUnlockerByID(unlockersDir, unlockerID string) (secret.Unlock
|
||||
tempUnlocker = secret.NewPGPUnlocker(v.fs, unlockerDirPath, metadata)
|
||||
case "keychain":
|
||||
tempUnlocker = secret.NewKeychainUnlocker(v.fs, unlockerDirPath, metadata)
|
||||
case "secure-enclave":
|
||||
tempUnlocker = secret.NewSecureEnclaveUnlocker(v.fs, unlockerDirPath, metadata)
|
||||
default:
|
||||
continue
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user