Thanks for explanation!
Regarding styles: The first code snippet is the one I was trying to use first. It indeed comes from iOS NetworkExtension which works perfectly.
The second code snippet I took from this forum and added it directly to NetworkExtensions handleAppMessage just for tests. Then added selection of keychain with a hope that temporary-exception entitlement would help.
After adding kSecUseDataProtectionKeychain: true both return the same error code: -25291 (errSecNotAvailable?).
Post
Replies
Boosts
Views
Activity
I have tried that, and when extension wants to write to the keychain, it always gets error 100001. A little more info and code example in another thread: https://developer.apple.com/forums/thread/672456?login=true&page=1#660300022
What is interesting is that it is possible to open the keychain (SecKeychainOpen returns 0), but when trying to write to it, it fails with the same 100001 code.
						let path = "~/Library/Keychains/login.keychain-db"
var keychain: SecKeychain?
var status = SecKeychainOpen(path, &keychain)
log.warning("SecKeychainOpen \(status)")
let addErr = SecItemAdd([
kSecClass: kSecClassGenericPassword,
kSecAttrService: "aTestTestTest",
kSecAttrAccount: "mrgumby",
kSecUseKeychain: keychain,
kSecValueData: "opendoor".data(using: .utf8)!
] as NSDictionary, nil)
if addErr != errSecSuccess {
log.warning("Keychain SecItemAdd failed, error: \(addErr)")
} else {
log.warning("Keychain success")
}
result:
SecKeychainOpen 0
Keychain SecItemAdd failed, error: 100001
Adding
<key>com.apple.security.temporary-exception.files.home-relative-path.read-write</key>
<array>
<string>/Library/Keychains/login.keychain-db</string>
</array>
To extension entitlements doesn't help.
It's a System Extension using NEPacketTunnelProvider (sandboxed, with incoming and outgoing connections enabled).
Not sure about the style of keychain usage. Here is the code:
var query = [String: Any]()
setScope(query: &query, context: context)
query[kSecClass as String] = kSecClassGenericPassword
query[kSecAttrAccount as String] = username
query[kSecAttrAccessible as String] = kSecAttrAccessibleAfterFirstUnlock
query[kSecValueData as String] = password.data(using: .utf8)
let status = SecItemAdd(query as CFDictionary, nil)
Status returns 100001.
Logs contain:
create /Library/Keychains/System.keychain.sb-ec3c9eec-Efos0S: Operation not permitted
Sandbox: my.app.bundle(19770) deny(1) file-write-create /Library/Keychains/System.keychain.sb-ec3c9eec-Efos0S
UNIX error exception: 1
CSSM Exception: 100001 UNIX[Operation not permitted]
CSSM Exception: 100001 UNIX[Operation not permitted]
Can you please explain what do you mean by "the bridge"?
I've found your message - https://developer.apple.com/forums/thread/672155 from a week ago, which suggests that system extension can't read a value from the keychain if it was written there by an app. So essentially there is no way to just pass persistent reference of a keychain entry from the app to sysex?
What do you think about such sequence: Send password from the app to system extension via sendProviderMessage -> handleAppMessage
Save it to the keychain from the system extension itself and keep using it in the system extension
Profit :)
One of the reasons why it should be persisted, is because system extension may be used not only from the app itself but also by the system. For example when connection was dropped or system went to sleep and is back, it asks extension to reconnect to VPN automatically, without the app intervention. At this point extension has to get the password from somewhere by itself.
Yes, there are few actually. One of them is that sandboxed system extensions (network extension) can't write log to file. Another is that the same extension can't read from keychain. But I'm not sure it is related to this error, as it (10006 error) actually went away lately.
Looks like when I try to write to the Keychain from extension, I get the same error on write.
Ohh, I'm so sorry! I missed one zero :(
It is #define PRIV_NET_PRIVILEGED_NECP_MATCH 10006 /* Privilege verified by Network Extension policies */. And the problem is in Network Extension indeed.
Maybe it is not because of writing to file, that was just my hypothesis. Any ideas on what can be the cause?
And thanks a lot for log commands, that's actually enough for me, and works much faster!
Catalina 10.15.7 (19H114)
Xcode Version 12.4 (12D4e)
Sandboxed app with sandboxed NetworkExtension (Packet tunnel). App can write logs to file inside its container without problems. When Extension tries to write to file, system-privilege 10006 appears in logs.
PS. Is there any possibility to stop Console app from removing older logs? Messages appear so fast that it is difficult to find anything useful before they disappear. And creating sysdiagnose reports everytime, takes too much time.
Here it is:
error 12:27:00.717255+0200 Sandbox: my.app.bundle.id(31524) System Policy: deny(1) system-privilege 10006 kernel
Looks like it pops-up every time a NetworkExtension tries to write to log file.
Were you able to find an underlying problem?
I also submitted a report in Feedback assistant regarding this issue: FB8978342.
At the moment the only workaround I see to make app a little more user friendly is to always return .replace in request(request: , actionForReplacingExtension, withExtension), because in this case if user has not yet allowed installation of extension, system modal will appear one more time asking user to do it. Of course this means that after user accepts it, app will flood extensions with installation requests all the time it tries to use its extension.
Another scenario:
OSSystemExtensionManager.shared.submitRequest(OSSystemExtensionRequest.activationRequest(...))
User sees system modal asking to go to the settings and enable extension, but presses OK and does nothing.
Next time app tries to submit new activation request one more time, delegate receives request( , actionForReplacingExtension, withExtension) and returns .cancel because versions are the same.
Delegates request(_ request: OSSystemExtensionRequest, didFailWithError error: Error) is called with error OSSystemExtensionError.requestCanceled.
Nowhere in this sequence app had a chance to know that user still hasn't accepted installation of the extension.
For future reference:
Working solution is to have two entitlements files, one of them having "-systemextension" added where needed and build settings setup in a way, that will use one file for debug build and other for release.
OK, but now the question is how to make XCode project work for signing with both Developer ID and simple development PPs?
If I add "-systemextension" to all network extension capabilities in entitlements file, XCode accepts my Developer ID. But now it complains if I select PP for development (with type: Development), because this one, when downloaded from developer.apple.com has network extension capabilities without "-systemextension".