ASN.1 structure of DER encoded entitlements

What is the actual ASN.1 structure of the DER encoded entitlements used for iOS and MacOS applications?

You can see a sample output at 'The Future is DER', but is there any official documentation or definition?

Answered by DTS Engineer in 817402022
So at the moment we have no choice but to read the entitlements ourselves.

So, yeah, DTS doesn’t support that.

Why are the Entitlement APIs from the Security Framework not available for iOS?

These SecTask APIs were originally intended to be used in IPC scenarios, and iOS doesn’t really support IPC [1]. However, I agree that there are plenty of other situations where being able to access your own entitlements would be helpful, and I encourage you to file an enhancement request for the APIs you need.

Please post your bug number, just for the record.

In the meantime, if you’re written a keychain wrapper the best option is to have your client supply the keychain access group info you need. That gets you out of this business entirely.

Oh, and apropos this:

the default application identifier (team ID + bundle ID)

The App ID prefix is not always the Team ID. Older projects might use a unique App ID prefix. If you’re writing a general purpose wrapper, make sure to take that into account.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] Many of the APIs are present and functionality, but either the iOS sandbox makes them irrelevant or their use cases are extremely restricted.

What is the actual ASN.1 structure of the DER encoded entitlements used for iOS and MacOS applications?

Why does that matter to you?

Most low-level code signing structures like this are not documented for third-party use. Rather, you’re expected to generate and parse them with Apple tools. In the case of entitlements, that means codesign, which continues to support the XML property list format for both signing and display.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

The Security Framework does not provide any of the Entitlement API functions such as SecTaskCopyValueForEntitlement for iOS, only for macOS. So at the moment we have no choice but to read the entitlements ourselves.

Why are the Entitlement APIs from the Security Framework not available for iOS? It just doesn't make sense!

An example where access to the entitlements is necessary at runtime:

When using the Keychain APIs and using keychain groups, it is very important to be able to get the team ID from the app's entitlements at runtime. When saving a keychain entry, the default application identifier (team ID + bundle ID) is used as the group if none is specified. However, when retrieving keychain items, there is no way to restrict them to items from the default group if you do not have the team ID.

This is an inherent design flaw that can be circumvented if the team ID can be retrieved.

There are many other scenarios in which it is at least helpful, and in some cases necessary, to read out certain Entitlement values at runtime. For example, to determine which APS environment is active, what the default data protection value is, etc.

So at the moment we have no choice but to read the entitlements ourselves.

So, yeah, DTS doesn’t support that.

Why are the Entitlement APIs from the Security Framework not available for iOS?

These SecTask APIs were originally intended to be used in IPC scenarios, and iOS doesn’t really support IPC [1]. However, I agree that there are plenty of other situations where being able to access your own entitlements would be helpful, and I encourage you to file an enhancement request for the APIs you need.

Please post your bug number, just for the record.

In the meantime, if you’re written a keychain wrapper the best option is to have your client supply the keychain access group info you need. That gets you out of this business entirely.

Oh, and apropos this:

the default application identifier (team ID + bundle ID)

The App ID prefix is not always the Team ID. Older projects might use a unique App ID prefix. If you’re writing a general purpose wrapper, make sure to take that into account.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] Many of the APIs are present and functionality, but either the iOS sandbox makes them irrelevant or their use cases are extremely restricted.

So, yeah, DTS doesn’t support that.

I can understand if it's not actively supported, but I wouldn't call providing technical documentation 'active support'. There are several official Apple articles on the subject, but most of them are not very detailed.

Wasn't the codesign utility once open source? Since the reorganisation of Apple's OSS pages, many things are not so easy to find.

Please post your bug number, just for the record.

The Feedback Assistant ID is FB16077892

(But for some reason my feedback seems to have been deleted immediately? At least I don't seem to be able to access it anymore)

Based on my experience over the last 15 years with this type of developer feedback for iOS development, it will be years before such a feature is available in iOS. If an implementation is considered at all.

In the meantime, we need a pragmatic solution.

Is SecTaskCopyValueForEntitlement considered a private API in the Security Framework, which if used on iOS will result in a rejection in the App Store review process?

In the meantime, if you’re written a keychain wrapper the best option is to have your client supply the keychain access group info you need. That gets you out of this business entirely.

This just shifts the problem to the application developer, who either has to abandon the use of the default keychain access group altogether, or try to construct the string for the default group himself.

The App ID prefix is not always the Team ID. Older projects might use a unique App ID prefix. If you’re writing a general purpose wrapper, make sure to take that into account.

Many thanks for the hint! Do you have more details on this? I can't remember when it was possible to define your own app ID prefix in the Developer Portal, not even in the older versions.

I can understand if it's not actively supported, but I wouldn't call providing technical documentation 'active support'.

I think the current situation is instructive. Presumably you built your code signature parsing code back when the entitlements were stored as a property list. Doing that was unsupported. That code broke when we switched to ASN.1, and hence this thread. I’m trying to avoid repeating this cycle, where your code breaks again the next time we revise the code signature format.

Remember, DTS’s goal is to help developers build products that work now and in the future. We don’t support things that run counter to that goal.

Wasn't the codesign utility once open source?

I’m not sure if codesign was ever open source, but the core code signing infrastructure is. It lives within the Security repo.

It’s absolutely possible for you to reverse engineer this stuff based on that source code. However doing so is again… you guessed it… unsupported. I’m not going to help you with that for the reasons I outlined above.

The Feedback Assistant ID is FB16077892

Thanks!

I took a quick look and it’s definitely landed in the right place. I’m not sure why you can’t see it in Feedback Assistant. If your unable to resolve that problem, let me know and I’ll try to suggest a path forward.

Is SecTaskCopyValueForEntitlement considered a private API in the Security Framework

I don’t use the term private API because IMO there are:

  • APIs, which are by definition public

  • Implementation details

You shouldn’t rely on implementation details. Apple is free to change them at any time [1].

which if used on iOS will result in a rejection in the App Store review process?

I don’t work for App Review and can’t give definitive answers on their behalf. However, in this case clause 2.5.1 of the App Review Guidelines is crystal clear.

Do you have more details on [unique App ID prefixes]?

The doc I usually point folks at is TN2311 Managing Multiple App ID Prefixes. I also touch on it in App ID Prefix Change and Keychain Access.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] I encountered a perfect example of this a few year’s back. A developer used the Darwin open source to uncover internal routines within CommonCrypto. Many years later we removed those routines [2], causing the developer’s app to break (r. 82893654). That put the developer in a real pickle:

  • Their deployed app was failing on the new OS release, seriously inconveniencing their customers.

  • There wasn’t an easy fix. If we remove or deprecate an API, we usually provide a path forward, but that’s not something we consider when changing implementation details.

  • So they had to rush to write and deploy some complex cryptographic code.

Fun times!

[2] The teams that maintain our cryptographic code are more likely to proactively remove stuff because they want to flush out any Apple code that’s using old cryptographic infrastructure.

[...] that code broke when we switched to ASN.1, and hence this thread.

In fact, that is not the case here, although I understand that you would like to use it as an 'instructive case'.

Nothing is broken yet in the implementations we are using, at the moment it is more about preventing something from breaking in the near future.

But yes, if you use a function or feature that is not officially supported or for which there is no API, there is always a risk that something will break after an internal change.

If you are aware of these dangers, you can act accordingly and plan ahead.

In particular, it is important to consider whether you want to and can wait years for an official solution to be implemented, or whether you need an immediate, viable solution.

Remember, DTS’s goal is to help developers build products that work now and in the future.

A noble and sensible goal.

Unfortunately, in practice, I have seen in several projects and with several customers that it takes years to get sustainable solutions at the (iOS / macOS) platform level. This applies to both features and bugs.

I'm happy to be positively surprised, but we'll see what happens in the future with Entitlement value retrieval on iOS.

I hope you understand, as I have explained, that it is not always possible to wait so long for a solution that may never come.

The doc I usually point folks at is TN2311

Thanks. I must have either forgotten or repressed this. The consequence of potentially losing all default keychain entries by changing the App ID was a rather drastic consequence of this change.

I am afraid we have gone a bit off topic, thank you for your comments and information.

I think we can end this thread with the simple answer to my original question that there is, or will be, no official documentation of the ASN.1 structure.

ASN.1 structure of DER encoded entitlements
 
 
Q