Keychain Code Signing Entitlements - Strange behavior, Keychain loss - ios

I had distributed an application in appstore with enabling the Keychain sharing by adding the Keychain Entitlement file.Initially, I thought to have two application sharing the same keychain but later I had only one application.Although keychain shared access is enabled in General capabilities in XCode and Entitlement file is added in code signing entitlements,I set nil value to access group in KeychainItemWrapper class as illustrated below.
KeychainItemWrapper *keychainWrapper = [[KeychainItemWrapper alloc]initWithIdentifier:KEYCHAIN_IDENTIFIER_NAME accessGroup:nil];
In the next release, I removed the Keychain Entitlement file and code signing entitlement as i felt its unnecessary but now the application is not able to access the previous version keychain item and returns null value.
Please explain me this strange behavior as in both version the
access group is always set to nil.
Also explain the keychain structure enabling and disabling Keychain
sharing.

If nil value is passed for KeychainBundleIdntifier then it will take the value of Bundle Identifier for a shared keychain the value would be shared keychain identifier in keychain entitlements.plist

Related

Catalyst app: How do I enable com.apple.developer.default-data-protection entitlement?

I am attempting to distribute a Catalyst app for beta testing. Since there's no Test Flight for Mac, my intent is to distribute a signed archive in order to minimize the amount warnings my users receive about running the app. I did the following:
Archived for MyMac,
Selected the archive from the "macOS Apps" list in the organizer,
Clicked "Distribute App,"
Chose "Developer ID."
Selected "Upload"
Selected "Automatically manage signing"
I expected it to be submitted for notarization, but instead received an error:
Provisioning profiled failed qualification. Profile doesn't include
the com.apple.developer.default-data-protection entitlement.
I subsequently checked the Mac OS Provisioning profile via developer.apple.com. I have a profile that's labeled "XC OSX:" (assuming that means Xcode auto-generated) with a type field of "Developer ID Application." Sure enough, although it shows iCloud, in app purchases, etc., in the "Enabled Capabilities" section it does not have Data Protection.
But, in Xcode, when I select the target and go to "Signing and Capabilities," Data Protection is already listed. When I click the information "i" button next to the MacOS provision profile, it says com.apple.developer.default-data-protection is enabled. (it actually shows that for both the IOS and the MacOS provisioning profile).
Next, I looked at the Bundle Identifier on developer.apple.com and see Data Protection listed under capabilities:
I tried removing and re-adding Data Protection in Xcode, but the error still occurs.
I tried manually creating a Developer ID profile on developer.apple.com, but the resulting profile still lacks Data Protection.
I tried removing and re-adding Data Protection under the identifier on developer.apple.com. This successfully invalidated the existing profiles (both Xcode's and the one I created). When I again attempted signing, a new profile was created but it still lacks Data Protection and the error still occurs.
What am I missing here? What else do I have to do to enable Data Protection in the provisioning profile?
As you figured out, the problem here is that the Data Protection entitlement is not available for MacOS.
If you still want to use this for your iOS version of the app, you need to use a different .entitlements file for your MacOS build to your iOS build.
Firstly, duplicate your current .entitlements file. The easiest way is to hold the Alt key while dragging the .entitlements file slightly. It will make a copy. Rename it to something like Original Name-MacOS.entitlements.
The next step is to open your Build Settings and type entitlements into the search bar.
You'll see your original entitlements file showing for both Debug and Release builds. Select the Debug row, then click the + button. Click on Any SDK and change it to Any macOS SDK. Now change the name of the entitlements file to your MacOS variant.
Repeat the process for the Release build so it looks like below.
The final step is to remove the offending entitlement from your MacOS .entitlements file. This has to be done manually as the Signing & Capabilities tab will only show the entitlements from your original iOS file. So click you MacOS .entitlements file and delete the Data Protection entry.
Clean your project, Build & Run, Export etc.. and you should be good to go.
Burned a support ticket and found the answer. I read the message as:
You failed. You don't have Data Protection (but you need it)
But per Apple, it actually means:
You failed. You want Data Protection (because you turned it on) but
don't have it (because it's not supported in this config).
So, the solution for "Data protection is missing" was... turn Data Protection off.
On MacOS, data protection APIs are not currently functional.
If you try to use them like this,
try data.write(to: fileUrl, options: .completeFileProtection
the code will compile and execute but the data is not being stored securely on the file system.
If you need to store data securely, there are several options available to you.
Passwords and related data can be stored in the Keychain and FileVault will encrypt all of the files on the disk transparently.
But if that's not sufficient for your needs. You can use the AES.GCM encryption API in CryptoKit to encrypt your content before writing it to disk.
let key = SymmatericKey(size: .bits256)
let sealed = try AES.GCM.seal(data, using: key)
Source: WWDC 2019 Introducing iPad Apps for Mac

iOS App Today Widget App Group Entitlement with Keychain Sharing Entitlement, Error on Device like Simulator -25243 (errSecNoAccessForItem)

Have an application that has been using Keychain Access for a bit and working fine.
Added a Today Widget and then added the App Group Entitlement.
All seems to be good, but now getting
CRASH: Couldn't add the Keychain Item Error
Domain=NSOSStatusErrorDomain Code=-25243
"The operation couldn’t be completed. (OSStatus error -25243.)".
When trying to use the keychain.
This is on a DEVICE and not in the simulator.
Using device because of testing with Push Notifications.
Have tried cleaning, updating profiles, etc.
XCode 6.3.1
Mini iPad iOS 8.3
The error -25243 is often caused by trying to access a keychain access group for which you don't have permissions because they might be missing from your Entitlements.plist file or your provisioning profile.
So you should do the following:
Check that you have your entitlements file in your project.
Try disabling/enabling entitlements.
Check that your app id has the required permissions enabled and that your provisioning profile(s) which you use with your build schema when you run the app on the devices have been regenerated with the new permissions/entitlements.
If everything is OK after checking up the above steps, my two cents would be that the provisioning profile that you use for your debug schema which you use to build the app to run on the device does not contain the required entitlements.
Edit: 4. According to the OP, one should also check if the value item for com.apple.security.application-groups in the entitlements file matches.

Does enabling Keychain Sharing alter your AppID?

I notice when I enable Keychain Sharing in Xcode for my iOS app Xcode says it will "Add the Keychain Sharing entitlement to your App ID", and it does appear to connect to my account because I get a popup asking which developer account to use. However on the dev portal there's no visible change to any of my App IDs, and my provisioning profile isn't invalidated like it sometimes is when I change an app's entitlements. Keychain Sharing isn't a visible option to enable/disable in the App ID, either.
Does anyone know what Xcode is doing under the covers here? The local change to the entitlements file is obvious, but I'd like to understand the App ID side of it.
Every keychain item in iOS contains an attribute called the keychain access group. An iOS app can only access those keychain items it has permission to. This permission comes from the code signing entitlements stamped into the app when it is signed.
By default, an app can only access keychain items with the keychain access group matching the application-identifier code signing entitlement. However, if a developer wants to share keychain items amongst their apps, they can add a custom keychain-access-groups code signing entitlement that specifies an array of keychain access groups that the app can access.
Normally one creates keychain items without setting the access group attribute kSecAttrAccessGroup. In that case, Keychain Services will automatically set that attribute to the default value. If there is no keychain-access-groups entitlement, the default is the value of the application-identifier entitlement. Otherwise the default is the value of the first array element in the keychain-access-groups entitlement.
When using the Xcode Capabilities editor on the target settings pane to turn on Keychain Sharing, Xcode will add the required App ID Prefix (Team ID) to the front of any listed Keychain Group items at build time. You can see that in the generated entitlements file represented by the build setting $(AppIdentifierPrefix).

SecItemCopyMatching returns errSecItemNotFound in release builds

I am working on an app that stores a password in the keychain. Everything is working fine when I run the app from Xcode using a development profile - I can save a password, quit the app, relaunch and fetch the password from the keychain.
However, whenever I run the app using an Ad Hoc or App Store profile SecItemCopyMatching always returns errSecItemNotFound when I try to fetch the password from the keychain after relaunching the app.
Is there something I missing with the app ID, provisioning profile or entitlements?
Turns out I was being caught out by the Enable Foundation Assertions build setting. It seems to be set to No by default for release builds.
I was using code from Keychain Services Tasks for iOS in the Apple Docs which has a lot of the keychain calls (including SecItemAdd) wrapped in NSAssert() therefore they weren't getting called and nothing was getting saved to the keychain.

Read from keychain results in errSecItemNotFound 25300

I store username & password using keychain, sometimes when I tried to get the password of the username, it told me errSecItemNotFound.
I keep that the password is always existed in keychain, so why it is not found?
Thanks.
Tony: that error is simply OSStatus error -34018 - client has neither application-identifier nor keychain-access-groups entitlements.
This could be happening as a result from using a nonstandard app signing method or some other problem with your entitlements. Make sure you're building simply out of Xcode and not using alternate signing methods unless you completely understand them.
When reading the keychain, make sure you always build with a provisioning profile linked with the appId that used to create the keychain record.
#graver
http://opensource.apple.com/source/Security/Security-55471/sec/Security/SecBasePriv.h
errSecMissingEntitlement = -34018, /* Internal error when a required entitlement isn't present. */

Resources