Skip to content

Commit 3d46554

Browse files
committed
Fix secure enclave private key access control
1 parent 5ef1914 commit 3d46554

File tree

2 files changed

+21
-3
lines changed

2 files changed

+21
-3
lines changed

flutter_secure_storage_darwin/darwin/flutter_secure_storage_darwin/Sources/flutter_secure_storage_darwin/FlutterSecureStorage.swift

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ class FlutterSecureStorage {
247247

248248
/// Ensures a Secure Enclave EC private key exists for the provided service, creating it if needed.
249249
@available(iOS 11.3, macOS 10.15, *)
250-
private func ensureEnclavePrivateKey(service: String?, accessControl: SecAccessControl?) throws -> SecKey {
250+
private func ensureEnclavePrivateKey(service: String?) throws -> SecKey {
251251
let tag = enclaveKeyTag(for: service) as CFData
252252

253253
let query: [CFString: Any] = [
@@ -271,6 +271,12 @@ class FlutterSecureStorage {
271271
kSecAttrApplicationTag: tag
272272
]
273273
]
274+
let accessControl = SecAccessControlCreateWithFlags(
275+
nil,
276+
kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
277+
.privateKeyUsage,
278+
nil
279+
)
274280
if let ac = accessControl {
275281
var privateAttrs = attributes[kSecPrivateKeyAttrs] as! [CFString: Any]
276282
privateAttrs[kSecAttrAccessControl] = ac
@@ -480,7 +486,7 @@ class FlutterSecureStorage {
480486
if #available(iOS 11.3, macOS 10.15, *) {
481487
let ac = createAccessControl(params: params)
482488
do {
483-
let privateKey = try ensureEnclavePrivateKey(service: params.service, accessControl: ac)
489+
let privateKey = try ensureEnclavePrivateKey(service: params.service)
484490
let aesKeyData = try unwrapSymmetricKey(wrappedKeyData, using: privateKey)
485491
let key = SymmetricKey(data: aesKeyData)
486492
// Encrypted blob format: nonce(12) + ciphertext+tag
@@ -558,7 +564,7 @@ class FlutterSecureStorage {
558564
if #available(iOS 11.3, macOS 10.15, *) {
559565
let ac = createAccessControl(params: params)
560566
do {
561-
let privateKey = try ensureEnclavePrivateKey(service: params.service, accessControl: ac)
567+
let privateKey = try ensureEnclavePrivateKey(service: params.service)
562568
guard let publicKey = SecKeyCopyPublicKey(privateKey) else {
563569
return FlutterSecureStorageResponse(status: errSecParam, value: nil)
564570
}
@@ -715,6 +721,17 @@ class FlutterSecureStorage {
715721
let status = SecItemCopyMatching(query as CFDictionary, &ref)
716722
return FlutterSecureStorageResponse(status: status, value: ref)
717723
}
724+
725+
internal func deleteEnclavePrivateKey(service: String?) {
726+
let tag = enclaveKeyTag(for: service) as CFData
727+
728+
var query: [CFString: Any] = [
729+
kSecClass: kSecClassKey,
730+
kSecAttrKeyType: kSecAttrKeyTypeECSECPrimeRandom,
731+
kSecAttrApplicationTag: tag
732+
]
733+
SecItemDelete(query as CFDictionary)
734+
}
718735
}
719736

720737
extension Result where Success == Bool, Failure == OSSecError {

flutter_secure_storage_darwin/darwin/flutter_secure_storage_darwin/Sources/flutter_secure_storage_darwin/FlutterSecureStorageDarwinPlugin.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ public class FlutterSecureStorageDarwinPlugin: NSObject, FlutterPlugin, FlutterS
119119
private func deleteAll(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) {
120120
let (params, _) = parseCall(call)
121121
let response = flutterSecureStorageManager.deleteAll(params: params)
122+
flutterSecureStorageManager.deleteEnclavePrivateKey(service: params.service)
122123
handleResponse(response, result)
123124
}
124125

0 commit comments

Comments
 (0)