Code Signing

RSS for tag

Certify that an app was created by you using Code signing, a macOS security technology.

Code Signing Documentation

Pinned Posts

Posts under Code Signing tag

261 Posts
Sort by:
Post marked as solved
3 Replies
307 Views
Hi, I'm a font designer and making pkg installers for my fonts. Before, I was using Hancock app to code sign my pkg files easily though using my old MBPro (15inch- mid2014). Now almost a month ago, I bought a new MacBook Pro (16-inch, 2019) and renew my subscription to Apple Developper program, when I downloaded my .cer file from "Certificates, Identifiers & Profiles" then import my .cer file through Keychain Access, It get loaded ok but it does not show on "My Certificates" even it's there at "Login" level. So Hancock app won't find it except if it's under "My Certificates" level... and I'm lost, I struggle to copy paste again to "My Certificates" but no way.... Thank you very much in advance for your kind help. Here is my website:  https://norfonts.ma  I'm also selling my fonts through NC :  https://www.notationcentral.com Thanks for you kind help, —Nor Eddine Bahha (Jazz Piani st & Font Designer)
Posted
by NorFonts.
Last updated
.
Post not yet marked as solved
2 Replies
171 Views
We have a desktop application we build using Cmake and Qt to build. I am able to codesign and notarize the app bundle and got "statusSummary": "Ready for distribution", in the log from notarization. I stapled to the .app and used ditto to zip it again but was still getting unidentified developer when I sent it to coworkers to try. I then ran create-dmg to create a dmg to distribute the application since this is our normal distribution method and was getting unverified developer warnings when sending and trying the application on other systems. I guessed that maybe I needed to codesign and notarize the .dmg as well so I did that and again got "statusSummary": "Ready for distribution", in the log but I am still seeing errors when trying to open and run on other systems. is there an order of operations I am missing in the process or a better way for me to test locally because everything I see on my end says its passing the checks.
Posted Last updated
.
Post marked as solved
5 Replies
400 Views
Hi, I am testing the behavior of my app if I change it's app bundle content. I created an app with a script within it's Resources folder. I signed the app and verify that the code sign is accepted with the spctl command. Then I modify the script within the app bundle and spctl gives me a sealed resource is missing or invalid which was expected. However I thought that I wouldn't be able to launch the app bundle now that it is compromised but I was able to execute it. Do I need to make it go through GateKeeper by first downloading the app from a server? In that case if I download an non-modified app, launch it successfully then modify it, would subsequent launch fail or not? The app will be delivered through MDM and I think that GateKeeper does not verify MDM-delivered apps. Is it possible to make the app non-launchable if the files within its Resources folder have been modify/compromised? Edit: The app won't be installed to /Applications/ but to a specific folder Thank you in advance!
Posted
by gmorimoto.
Last updated
.
Post not yet marked as solved
1 Replies
138 Views
I get the following error... Warning: unable to build chain to self-signed root for signer "Mac Developer: J I have tried everything.. all of the suggestions listed and still can't clear the problem. Can we get a better description of what the problem is so we might get a better idea on how to fix this. I am running XCode 10.0 on OSX 10.13.6 I need to ship product. Help!! Any help... Thx
Posted
by yurchik1.
Last updated
.
Post not yet marked as solved
5 Replies
437 Views
Hi all, I'm attempting to distribute a notarized expiring demo variant of my Mac App Store app (TypeMetal) directly to potential customers as a download on our website, using the procedure documented here: https://developer.apple.com/documentation/security/notarizing_macos_software_before_distribution I successfully complete the 9 steps listed in "Notarize Your App Automatically as Part of the Distribution Process", including choosing "Developer ID (Distribute directly to customers)" and "Upload (Send to Apple notary service)", and successfully download the resultant .app bundle, but I'm unable to run the app. It looks to me as if the system is attempting to obtain an App Store receipt for the app, when what I want is for this variant of the app to be treated as distinct from the purchased Mac App Store version, and be runnable without purchase. I have tried changing the app's bundle identifier and removing the LSApplicationCategoryType (in the Xcode target's settings, before building), but neither seems to affect these results. I'm left wondering how the system is determining that this is an .app that requires App Store sign-in/receipt-checking. When I copy the downloaded, notarized .app to a different macOS user account, log in as that user, and attempt to launch it there, the system presents a panel, prompting for the user to sign in with their Apple ID: When I attempt to launch the app in my own user account (the one I build and develop in), the system presents the same prompt in a slightly different form: Whether or not I provide a valid Apple ID sign-in in either case, the launched app then terminates with a fatal alert. (Same result in a separate user account as in my own development account.) I would like for the distributed app to be runnable by customers without requiring an App Store receipt. I have verified that my own App Store receipt-checking code is being omitted, as I intend, from the build I that submit for notarization. Is there something I need to do differently to make this work? The notarized app has passed the checks described here: Resolving Common Notarization Issues https://developer.apple.com/documentation/security/notarizing_macos_software_before_distribution/resolving_common_notarization_issues#3087721 I can provide the outputs of the codesign and spctl checks recommended on that page, if that would be helpful. The .app contains one embedded framework (OpenSSL.framework) and one command-line executable (tidy), but I believe they are correctly code-signed. I'm testing this on a 2020 M1 MacBook Air running macOS 12.3.1 (21E258), using Xcode 13.3.1 (13E500a) to do the build, upload for notarization, and export of the notarized result. Thanks very much in advance for any insight you can offer. Troy Stephens Coherence Labs, LLC
Posted Last updated
.
Post not yet marked as solved
1 Replies
188 Views
Example for google.com as an item name, I have two keychain items with the name "Foo", one in KeychainA another in keychainB. When I run the following which password should be retrieved? Password from KeychainA or KeychainB? Does it retrieve items from keychains by prioritizing retrieval from 'default' keychain first? Or it's sorted by the keychain name? or it prioritizes items based on date? security find-generic-password -w -s 'google.com' -a 'Foo' I asked because we often have certs that are duplicated across keychains and when I run the command above, the item is retrieved from a locked keychain. Which causes an OS prompt and that halts our Jenkins/CI.
Posted
by honey9.
Last updated
.
Post not yet marked as solved
1 Replies
149 Views
I have two certs with same name so prevent the ambiguity that codesign has when it finds two certs with same name in the keychain, I tried to create a new keychain and moved the cert I want into it and passed the path with --keychain param to the codesign tool. But it still looks for the cert in the login keychain. What's wrong with the below command? codesign -fs "$CODE_SIGN_IDENTITY" --keychain "full/path/to/codesigning.keychain-db" $FILE
Posted Last updated
.
Post marked as solved
1 Replies
220 Views
I added a Camera Extension to my app, using the template in Xcode 13.3.1. codesign tells me that the app and its embedded system extension are correctly signed, their entitlements seem to be okay. But when I submit an activation request for the extension, it returns with this failure: error: Error Domain=OSSystemExtensionErrorDomain Code=9 "(null)" localized failure reason: (null) localizedDescription: The operation couldn’t be completed. (OSSystemExtensionErrorDomain error 9.) localizedRecoverySuggestion: (null) What could be the reason? code 9 appears to mean a "validation error", but how do I figure out what is invalid?
Posted
by ssmith_c.
Last updated
.
Post not yet marked as solved
12 Replies
21k Views
Hello Everybody,I have 2 teams under my only Apple ID, a regular paid one (Agent) and a "personal team" (Free). I really want to get ride of "Personal Team" and its provisioning profiles since my XCode keep adding my bundle Identifiers to the free account and I have no control over them. I checked my developer panel but it seems that I can manage the free acount from there. Please let me know if there is way to fix that.Thank you
Posted
by shahram.
Last updated
.
Post marked as solved
2 Replies
267 Views
Just switched from a M1 MacBook Air back to an Intel Mac mini 2018 (not sure if it matters) and in the first try to distribute an app to the App Store I got a new error. The error states: The cloud signing service returned an invalid signature for It is failing when signing bundled universal binaries that where already signed before and are already in the App Store, no modification to that binaries. Replacing them with flat versions (Intel or Apple Silicon ones) works properly and the distribution process completes, but obviously the universal ones are needed. The error asks to fill a bug report but being familiar to bug reporting I know I can get some feedback tomorrow, in two years or never. Anyone else found this one? Any idea what can fix this or the best way to get in touch with Apple for a prompt fix?
Posted
by aonez.
Last updated
.
Post not yet marked as solved
0 Replies
362 Views
IMPORTANT This post is now retired in favour of TN3126 Inside Code Signing: Hashes. I’m leaving the original post here just for the record, but you should consider the official documentation authoritative. I was explaining code signing to someone today and, well, at the end of that conversation I found that I’d ‘accidentally’ written up a high-level description of how code signing works (-: Rather than let that go to waste, I thought I’d post a copy here. IMPORTANT This is all implementation details. You don’t need this info in order to sign your product for Apple platforms. If you use Xcode, it takes care of code signing for you. If you build a Mac product outside of Xcode, follow the advice in: Creating Distribution-Signed Code for Mac Packaging Mac Software for Distribution However, sometimes it’s useful to know a little bit about the man behind the curtain. It allows you to make better design choices and debug leaky abstraction layers. And hey, sometimes it’s just fun to know this stuff! If you have questions about code signing, put them in a new thread here on DevForums. Tag it with Code Signing so that I see it. Finally, if you really want to know how code signing works, most, maybe even all, of the implementation is available in Darwin. Specifically, look in the xnu project for the kernel side of it and the Security for the user space side. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" A Peek Behind the Code Signing Curtain Code signing is a fundamental technology on Apple platforms. The vast majority of developers don’t need to know how code signing works. They use Xcode, which takes care of the fiddly details. And, if they run into problems, those are usually related to high-level concepts — signing identities, entitlements, provisioning profiles — not the core code signing implementation. However, that’s not always the case. Every now and again an issue crops up where you actually need to understand how code signing works. For example: My Signing code for older versions of macOS on Apple Silicon post explains how to work around a code signing issue that cropped up during the early days of Apple silicon. It’s easier to understand issues like this if you understand some core code signing concepts. Using the Latest Code Signature Format has a diagnostic process that involves code signing hash slots. While the diagnostic itself is useful, it makes more sense if you know what those slots are for. The issue covered by Updating Mac Software makes more sense once you understand code signing’s lazy per-page signature checking. The goal of this post is to explain some of these core code signing concepts so that you can better understand, and potentially debug, weird code signing issues. I want to stress that this description is not comprehensive. I’ve elided various details for various reasons: Some stuff I haven’t yet researched in depth, some stuff is only interesting from a historical perspective, and some stuff is not relevant to my overall goal. My focus here is on macOS but these core code signing concepts apply to all Apple platfroms. Finally, a word of warning… WARNING Code signing has changed in the past and you can reasonably expect it to change again in the future. If you build a product that relies on these details, you must accept the compatibility risks that this entails. Reading this post is like reading the Darwin source: You’ll learn a lot, but you need to be careful about how you apply that knowledge. Code Signature Storage The code signature for an item is stored in one of four ways: If the item is a Mach-O image, or is a bundle wrapped around a Mach-O image, the code signature is stored within the image. % otool -l "/Applications/PCalc.app/Contents/MacOS/PCalc" | grep LC_CODE_SIGNATURE -B 1 -A 3 Load command 38 cmd LC_CODE_SIGNATURE cmdsize 16 dataoff 3170576 datasize 60656 If the item is a bundle without a Mach-O image, the code signature is stored in the bundle’s _CodeSignature directory: % codesign -d -vvv Test.bundle … Format=bundle … Authority=Apple Development: Quinn Quinn (7XFU7D52S4) … % find Test.bundle Test.bundle Test.bundle/Contents Test.bundle/Contents/_CodeSignature Test.bundle/Contents/_CodeSignature/CodeResources Test.bundle/Contents/_CodeSignature/CodeDirectory Test.bundle/Contents/_CodeSignature/CodeRequirements-1 Test.bundle/Contents/_CodeSignature/CodeSignature Test.bundle/Contents/_CodeSignature/CodeRequirements Test.bundle/Contents/Info.plist If the item exists within a bundle, it’s covered by the bundle’s code signature, as discussed below. Otherwise, the code signature is stored in extended attributes (EAs) on the item: % cat hello.txt Hello Cruel World! % codesign -d -vvv hello.txt … Format=generic … Authority=Apple Development: Quinn Quinn (7XFU7D52S4) … % ls -l@ hello.txt -rw-r--r--@ 1 quinn staff 19 14 Mar 22:09 hello.txt com.apple.cs.CodeDirectory 129 com.apple.cs.CodeRequirements 168 com.apple.cs.CodeRequirements-1 165 com.apple.cs.CodeSignature 4860 IMPORTANT Storing a code signature in EAs is brittle because many file transfer mechanisms drop these. If you follow the rules in Placing Content in a Bundle, none of your files will have code signature EAs. Code Directory The central concept in a code signature is the code directory. This is a data structure that holds all of the info about the code being signed. It’s this data structure that’s signed as part of the signing process [1], and it’s the hashes in this data structure that seal the code, resources, and metadata of your product. If you have a universal binary then each architecture is signed independently, so each has its own code directory. Hashing the code directory results in a code directory hash, or cdhash. This value uniquely identifies the code being signed. It crops up in a variety of places, most notably notarisation. A notarised ticket is actually a set of cdhash values that have been signed by the notary service. A code directory can be hashed by different algorithms, resulting in different cdhash values. Most code has a SHA-1 and a SHA-256 cdhash: % codesign -d -vvv "/Applications/PCalc.app" … CandidateCDHash sha1=eca4d50c1736d878a5c4f5f7994960735311f314 CandidateCDHashFull sha1=eca4d50c1736d878a5c4f5f7994960735311f314 CandidateCDHash sha256=a9b23d5ca054140c96fb770ee8391d96d8515923 CandidateCDHashFull sha256=a9b23d5ca054140c96fb770ee8391d96d8515923804608438e2629770d5792c6 Hash choices=sha1,sha256 … CDHash=a9b23d5ca054140c96fb770ee8391d96d8515923 … The CDHash property is the One True CDHash™. The CandidateCDHash and CandidateCDHashFull properties are alternative cdhash values, each specifying a hash algorithm. The Full variant includes the full hash, while the other variant is truncated to 20 bytes to match SHA-1. This structure was set up to enable stronger hashes (SHA-256) while still allowing the code to run on systems that only understand the old hashes (SHA-1). There’s a bunch of fine detail for this that I’ve not researched in depth. Also note that you’ll get different values for each architecture. The example above was run on Intel, and so you get the Intel architecture’s cdhash. To get the Apple silicon one, specify the --arch argument: % codesign -d -vvv --arch arm64 "/Applications/PCalc.app" … CDHash=28cf639f72ac35f8d57d45a118c101a2285f0a31 … [1] This uses CMS (Cryptographic Message Syntax) but I’m not going to go into those details here. Per-Page Hashes Within a code directory there are a set of hash slots. For a summary, look at the CodeDirectory property: % codesign -d -vvv "/Applications/PCalc.app" … CodeDirectory v=20500 size=25155 flags=0x10000(runtime) hashes=775+7 location=embedded … This means there are 775 per-page hash slots and 7 special hash slots. Add more -v options to see a dump of these hashes: % codesign -d -vvvvvv "/Applications/PCalc.app" … Page size=4096 -7=86f48b256e85ed00d054bbe3bad62b424baf1028c91cb7b193d1d3f8ebbe3f4e -6=0000000000000000000000000000000000000000000000000000000000000000 -5=bffee242018e6a39c46389fd913486fa29b3304712d32dd433f22d33b5a95da3 -4=0000000000000000000000000000000000000000000000000000000000000000 -3=8bee5419a9d27b02eee8f9897b6b94007b972cba348e4c863aa10df039b4b6c3 -2=a9ff3a03b94f75fcdea2208d8a8fadabc4cf5e4b2d4e6835a14508d1686a99b6 -1=f88548eecf39aa2e159365a9d4f0274a429e0793480abc8026d49fb2a8bf9ee9 0=07b91feb157b8238efb3d8149bacf546dc1ded500449cfd7d5b6a8bf1ebb4b34 1=f2f49595ca9daa599b4c41b69d99b6fede89eea39fa2000b452c7e26e06b8ddc 2=d62187f6573798dce6752a05aea083ae14c050e429fbc76d2092379c3533ebe5 3=a5a23c9cd825492a0ed5b5f541f2bbf12941bb8056f987f9d4e0f04d0885471f … 774=f6d1072647ec9f0e79a55c772f5e31699bbb1c3c424a2d48f64d0b896ae5c255 … The negative slots are special. More on that below. The non-negative slots are for per-page hashes, that is, 0 is the hash for the first page of code, 1 for the second, and so on. This per-page architecture means that the kernel can check each page as its loaded into memory. That is, if you take a page fault on a memory mapped file that’s code signed then, as part of satisfying that fault, the kernel may choose to verify the hash of the page’s contents. This allows the system to run a code-signed executable and check its code signature lazily [2]. macOS does not always check code as it is paged in. One key feature of the hardened runtime is that it opts the process in to this checking by default. The com.apple.security.cs.disable-executable-page-protection entitlement opts you out of this and other security features. Don’t do that! [2] I’m using the computer science definition of lazy here. Special Slots Within the code directory the negative hash slots are special. They don’t correspond to code but rather to other data structures. Each slot number corresponds to a specific type of data. I’m not going to give a comprehensive list, but here’s some highlights: Slot -1 holds a hash of the Info.plist. Slot -3 holds a hash of the resources. Slot -5 holds a hash of the entitlements. Consider this: % codesign -d -vvvvvv "/Applications/PCalc.app" … Page size=4096 … -1=f88548eecf39aa2e159365a9d4f0274a429e0793480abc8026d49fb2a8bf9ee9 … % shasum -a 256 "/Applications/PCalc.app/Contents/Info.plist" f88548eecf39aa2e159365a9d4f0274a429e0793480abc8026d49fb2a8bf9ee9 … The Info.plist hash matches the value in its hash slot. Neat-o! Now consider this advice from Using the Latest Code Signature Format: If -5 contains a value and -7 contains a zero value, or is not present, you need to re-sign your app to include the new DER entitlements. You should now have a better handle on this diagnostic. Slot -5 holds the hash for the old school property list entitlements while slot -7 holds the hash for the new-style DER entitlements. If you have an entry in -5, that is, you have entitlements, but have no entry in -7, then you’re missing your new-style DER entitlements and you must re-sign to run on iOS 15. Resources If your code exist in a bundle then the code signature protects not just your code but the resources in your bundle. Central to this is the CodeResources file. Slot -3 in the code directory holds the hash of that file: % codesign -d -vvvvvv "/Applications/PCalc.app" … Page size=4096 … -3=8bee5419a9d27b02eee8f9897b6b94007b972cba348e4c863aa10df039b4b6c3 … % shasum -a 256 "/Applications/PCalc.app/Contents/_CodeSignature/CodeResources" 8bee5419a9d27b02eee8f9897b6b94007b972cba348e4c863aa10df039b4b6c3 … So, if that file changes, the code directory hash changes and you break the seal on the code signature. Now let’s look at that file: % plcat "/Applications/PCalc.app/Contents/_CodeSignature/CodeResources" … <dict> <key>files</key> <dict> … </dict> <key>files2</key> <dict> … </dict> <key>rules</key> <dict> … </dict> <key>rules2</key> <dict> … </dict> </dict> </plist> It’s a property list with four top-level dictionaries: files, files2, rules, and rules2. Amusingly, three out of four of these items are vestigial. The one that matters is files2. Note The files dictionary contains SHA-1 hashes and is present for compatibility purposes. The rules and rules2 dictionaries are associated with resource rules, a concept that’s now obsolete. For more on the move away from resource rules, see Technote 2206 macOS Code Signing In Depth. The files2 dictionary contains two kinds of items. Firstly, there are references to resources. For example: % plutil -convert xml1 -o - "/Applications/PCalc.app/Contents/_CodeSignature/CodeResources" … <dict> … <key>files2</key> <dict> … <key>Resources/PCalc.help/Contents/Resources/PCalc.png</key> <dict> <key>hash</key> <data> wLi4SwDuno06WheWgINYKVT6LMg= </data> <key>hash2</key> <data> srK8T824L2l18d9eBixJC9nr3NUGCBh7L6qwsglQqFo= </data> </dict> … </dict> … </dict> </plist> % shasum -a 256 "/Applications/PCalc.app/Contents/Resources/PCalc.help/Contents/Resources/PCalc.png" b2b2bc4fcdb82f6975f1df5e062c490bd9ebdcd50608187b2faab0b20950a85a … % base64 -D | xxd -p srK8T824L2l18d9eBixJC9nr3NUGCBh7L6qwsglQqFo= b2b2bc4fcdb82f6975f1df5e062c490bd9ebdcd50608187b2faab0b20950 a85a As you can see, the hash2 property contains the SHA-256 checksum of the resource. The other kind of item is nested code. For example: % plutil -convert xml1 -o - "/Applications/PCalc.app/Contents/_CodeSignature/CodeResources" … <dict> … <key>files2</key> <dict> <key>Library/LoginItems/PCalc Widget.app</key> <dict> <key>cdhash</key> <data> 3pJUbWYNPPnlN8SNi1CAgdzIRWg= </data> <key>requirement</key> <string>(anchor apple generic and certificate leaf[field.1.2.840.113635.100.6.1.9] /* exists */ or anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = "9A6GM5K6XE") and identifier "com.pcalc.helper"</string> </dict> … </dict> … </dict> </plist> The cdhash property contains the code directory hash of the nested code: % codesign -d -vvv "/Applications/PCalc.app/Contents/Library/LoginItems/PCalc Widget.app" … CDHash=de92546d660d3cf9e537c48d8b508081dcc84568 … % base64 -D | xxd -p 3pJUbWYNPPnlN8SNi1CAgdzIRWg= de92546d660d3cf9e537c48d8b508081dcc84568 See, I told you cdhash values crop up all over the place! The requirement property contains the designated requirement (DR) of that nested code: % codesign -d -r - "/Applications/PCalc.app/Contents/Library/LoginItems/PCalc Widget.app" … designated => (anchor apple generic and certificate leaf[field.1.2.840.113635.100.6.1.9] /* exists */ or anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = "9A6GM5K6XE") and identifier "com.pcalc.helper" In theory this lets you update the nested code with a new version, as long as it has the same DR. No one ever does this in practice (-: For more information about code signing requirements, see Code Signing Guide, and specifically the Code Requirements section and the Code Signing Requirement Language appendix.
Posted
by eskimo.
Last updated
.
Post not yet marked as solved
0 Replies
2.3k Views
IMPORTANT This post is now retired in favour of TN3125 Inside Code Signing: Provisioning Profiles. I’m leaving the original post here just for the record, but you should consider the official documentation authoritative. I regularly help folks with code signing issues and have learnt that a lot of people are confused by the whole concept of a provisioning profile. This is my attempt to clear that up (-: Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" What exactly is a provisioning profile? Apple platforms will not run arbitrary third-party code [1]. All execution of third-party code must be specifically authorised by Apple. This is done using a provisioning profile [2], which describes five requirements: Who is allowed to sign code? What apps [3] are they allowed to sign? Where can those apps run? When can those apps run? How are those apps entitled? When the developer web site creates a profile [4] it cryptographically signs it. When you run an app on a device, the device checks this signature to determine if the profile is valid and, if so, checks that all of the app’s requirements are met by that profile. [1] Except for macOS, although provisioning profiles are still relevant on macOS, as we’ll see later. [2] There is an interesting edge case here. When you submit your app to the App Store, it re-signs your app as part of the distribution process. Before doing that, it checks that the app is signed and provisioned correctly. That ingestion check means that each individual iOS device does not need to perform further security checks, so the final app does not have a provisioning profile. However, this third-party code was still, technically, authorised by a profile, albeit during the App Store ingestion process. [3] In this document I’m using the term app to refer to a main executable packaged in a bundle structure. So everything I say about apps also applies to app extensions, App Clips (iOS), system extensions (macOS), and XPC Services (macOS). [4] Either directly, using the web site itself, or indirectly, using tools like Xcode. Unpack a Profile A profile is a property list wrapped within a CMS signature [1]. To view the original property list, remove the CMS wrapper using the security tool: % security cms -D -i Profile_Explainer_iOS_Dev.mobileprovision -o Profile_Explainer_iOS_Dev.plist % cat Profile_Explainer_iOS_Dev.plist … <dict> … lots of properties … </dict> </plist> IMPORTANT The exact format of a provisioning profile is not documented and could change at any time. I discuss these details here because I think it’s useful to understand how things work under the covers. I recommend against building a product based on these details; if you do build such a product be prepared to update it as the Apple development story evolves. [1] Cryptographic Message Syntax, as defined by RFC 5652. The Who Every profile has a DeveloperCertificates property holding the certificates of each developer who is allowed to sign code that’s covered by the profile. For example: % cat Profile_Explainer_iOS_Dev.plist … <dict> … <key>DeveloperCertificates</key> <array> <data>MIIFxDCC…tOLykA==</data> … more certificates … </array> … </dict> </plist> Use PlistBuddy to extract a specific certificate: % /usr/libexec/PlistBuddy -c "Print :DeveloperCertificates:0" Profile_Explainer_iOS_Dev.plist > cert0.cer % certtool d cert0.cer Serial Number : 7E FF 9C 91 BB EB D8 AB 42 81 52 35 64 F9 0F 72 Issuer Name : Common Name : Apple Worldwide Developer Relations Certification Authority … Subject Name : … Common Name : Apple Development: Quinn Quinn (7XFU7D52S4) … Not Before : 09:15:23 Apr 21, 2021 Not After : 09:15:22 Apr 21, 2022 … The What Most profiles apply to a single App ID. This is encoded in the Entitlements > application-identifier [1] property: % cat Profile_Explainer_iOS_Dev.plist … <dict> … <key>Entitlements</key> <dict> … <key>application-identifier</key> <string>SKMME9E2Y8.com.example.apple-samplecode.ProfileExplainer</string> … </dict> … </dict> </plist> This property holds an App ID, composed of an App ID prefix (SKMME9E2Y8 in this example) and a bundle ID (com.example.apple-samplecode.ProfileExplainer). It is also possible to create a profile for a wildcard App ID: % security cms -D -i Profile_Explainer_Wild_iOS_Dev.mobileprovision -o Profile_Explainer_Wild_iOS_Dev.plist % cat Profile_Explainer_Wild_iOS_Dev.plist <dict> … <key>Entitlements</key> <dict> … <key>application-identifier</key> <string>SKMME9E2Y8.com.example.apple-samplecode.*</string> … </dict> … </dict> </plist> </plist> This profile is valid for any App ID starting with SKMME9E2Y8.com.example.apple-samplecode. [1] On macOS this is Entitlements > com.apple.application-identifier. The Where Most profiles apply to a specific list of devices. This is encoded in the ProvisionedDevices property: % cat Profile_Explainer_iOS_Dev.plist … <dict> … <key>ProvisionedDevices</key> <array> <string>00008030-001544522E60802E</string> </array> … </dict> </plist> App Store distribution profiles have no ProvisionedDevices property because you can’t run a distribution-signed app locally. Developer ID and In-House (Enterprise) distribution profiles have the ProvisionsAllDevices property, indicating that they apply to all devices. The When Every profile has an ExpirationDate property which limits how long the profile remains valid. For example: % cat Profile_Explainer_iOS_Dev.plist … <dict> … <key>ExpirationDate</key> <date>2022-07-23T14:30:34Z</date> … </dict> </plist> Developer ID profiles do not expire and thus their expiration date is far in the future. The How Every profile has an Entitlements property which authorises the app to use specific entitlements. For example: % cat Profile_Explainer_iOS_Dev.plist … <key>Entitlements</key> <dict> <key>application-identifier</key> <string>SKMME9E2Y8.com.example.apple-samplecode.ProfileExplainer</string> <key>keychain-access-groups</key> <array> <string>SKMME9E2Y8.*</string> <string>com.apple.token</string> </array> <key>get-task-allow</key> <true/> <key>com.apple.developer.team-identifier</key> <string>SKMME9E2Y8</string> </dict> The entitlements in the profile act as an allowlist. This is not the same as the entitlements claimed by the app. To actually claim an entitlement you must include the entitlement in the app’s code signature. Every entitlement claimed by the app must be in the profile’s allowlist [1] but the reverse is not true. It’s fine for the allowlist to include entitlements that the app does not claim. The wildcard syntax only make sense in a profile’s allowlist. In the above example, SKMME9E2Y8.* means that the app can claim any keychain access group starting with SKMME9E2Y8. Wildcards do not make sense in the app’s code signature. To dump the entitlements claimed by the the app, use codesign with the --entitlements argument: % codesign -d --entitlements :- ProfileExplainer.app … <dict> <key>application-identifier</key> <string>SKMME9E2Y8.com.example.apple-samplecode.ProfileExplainer</string> <key>keychain-access-groups</key> <array> <string>SKMME9E2Y8.com.example.apple-samplecode.ProfileExplainer</string> </array> <key>get-task-allow</key> <true/> <key>com.apple.developer.team-identifier</key> <string>SKMME9E2Y8</string> </dict> </plist> As you can see, every entitlement claimed here is allowed by the profile, and thus the app should run. Note that the keychain-access-groups value, SKMME9E2Y8.com.example.apple-samplecode.ProfileExplainer, starts with SKMME9E2Y8.* and thus is allowed by the wildcard. [1] Except on macOS, as discussed in the next section. Entitlements on the Mac A macOS app can claim certain entitlements without them being authorised by a provisioning profile. These unrestricted entitlements include: com.apple.security.get-task-allow [1] com.apple.security.application-groups [2] Those used to enable and configure the App Sandbox Those used to configure the Hardened Runtime Other entitlements must be allowlisted by a provisioning profile, just like on iOS. This is an important security feature on macOS. For example, the fact that the keychain-access-groups entitlement must be allowlisted by a profile means that other developers can’t impersonate your app in order to steal its keychain items. [1] On iOS this is named get-task-allow and, as with all entitlements on iOS, must be allowlisted by the profile. [2] App Groups work differently on macOS and iOS; see this post for the gory details. Profile Location Historically it was common to install provisioning profiles on the device as a whole (in Settings on iOS or System Preferences > Profiles on the Mac). That’s still possible, but standard practice is to embed the profile within the app itself: iOS expects to find the profile at MyApp.app/embedded.mobileprovision. macOS expects to find the profile at MyApp.app/Contents/embedded.provisionprofile. Note The platforms use different file name extensions for these profiles (.mobileprovision on iOS, .provisionprofile on macOS) App Store apps do not contain an embedded provisioning profile because the App Store checks that the app is signed and provisioned correctly as part of its app ingestion process.
Posted
by eskimo.
Last updated
.
Post not yet marked as solved
6 Replies
590 Views
I am yet another another developer facing the issue of having a notarized application cryptically blocked by GateKeeper with the unhelpful "unidentified developer" message. I followed Eskimo's instructions of combing the system logs, and caught an event by XprotectService: File /Applications/Cook-a-Dream.app/Contents/Resources/app_packages/PySide6/lupdate failed on rPathCmd /Users/qt/work/install/lib/QtCore.framework/Versions/A/QtCore Googling around, I found some people reporting similar problems (with other libraries) being fixed by detecting and fixing this kind of problem by deleting/changing some of the rpaths with install_name_tool. The questions: How do I confirm if the issue is indeed one of rpath? What are the general "rules" that govern what is allowed or not allowed in terms of rpaths for GateKeeper? Can I add a prophylactic step to my workflow to detect those issues before notarization?
Posted
by EduardoV.
Last updated
.
Post not yet marked as solved
3 Replies
7.9k Views
I have a individual team with my dev account. I have recently got an invite for another team. I accepted the invite and now I need to sign the application and upload for that team. The new team however is not showing up in Xcode as an option and only shows my individual team. How do I get the new team added as an option within Xcode?
Posted
by Zzak0128.
Last updated
.
Post not yet marked as solved
6 Replies
1.1k Views
I have some issues linking some frameworks when I run my iOS application. The issue comes as code signing version is not supported. I use Carthage for the dependency management. It links the framework then has the copy-framework script where it copies to the framework and does the code signing. For code signing it does the same thing codesign --force --sign ****** --preserve-metadata=identifier,entitlements path_to_framework The CodeDirectory for some frameworks after signing is 20200 and for others 20400. Obviously 20200 is not supported anymore hence the issue, although I don’t under why does it assign an old version number to it when it's been signed the same way in Big Sur. I have Xcode 12.3 and using Big Sur 11.4. Framework where it’s not working: Executable=********/Frameworks/FirebaseCore.framework/FirebaseCore Identifier=com.firebase.Firebase-FirebaseCore Format=bundle with generic CodeDirectory v=20200 size=226 flags=0x0(none) hashes=1+3 location=embedded Signature size=4886 Signed Time=18 Jun 2021 at 16:15:27 Info.plist entries=7 TeamIdentifier=******** Sealed Resources version=2 rules=10 files=1 Internal requirements count=1 size=196 Framework where the code signing works properly: Executable=********/Frameworks/RxSwift.framework/RxSwift Identifier=io.rx.RxSwift Format=bundle with Mach-O universal (arm64) CodeDirectory v=20400 size=74833 flags=0x0(none) hashes=2332+3 location=embedded Signature size=4886 Signed Time=18 Jun 2021 at 16:16:07 Info.plist entries=21 TeamIdentifier=******** Sealed Resources version=2 rules=10 files=0 Internal requirements count=1 size=176 Any idea what the issue can be?
Posted
by adamglo.
Last updated
.
Post not yet marked as solved
4 Replies
159 Views
After a lot of googling, I'm still unable to find an answer. We are building our product within Azure Pipelines with macOS hosts. After the pipeline is done, we get corrupted packages out of it. I could reproduce it locally with 12.3.1. As you can see below, after overwriting the code sign, it fails to validate. Anyone got any idea how this can happen? Btw, we don't have any embedded bundles, same result without --deep, the notarization reports on the same file: The signature of the binary is invalid. # Force to override any codesign codesign --force --deep --sign "***" --timestamp --options=runtime ***.app # Verify the codesign codesign -vvv --deep --strict ***.app ***.app: a sealed resource is missing or invalid file modified: /Users/***/Desktop/***.app/Contents/MacOs/*** Only one file is having this issue, that is the main binary that is specified in the Info.plist as the startup program.
Posted Last updated
.
Post not yet marked as solved
0 Replies
175 Views
Hello! I was able to add the plugin upgrading xcode version to 13. I test my app and everything is working but then i try to archive the .ipa and upload it to the appStore but I face with this error: CFBundleIdentifier Collision. There is more than one bundle with the CFBundleIdentifier value 'com.onevcat.Kingfisher' under the iOS application 'WorkoutMinister.app'. With error code STATE_ERROR.VALIDATION_ERROR.90685 for id c3d0e0ae-8bce-4e4f-a335-2244043d4a3d I look for information but it and I know that is caused by embed framework reference inside the xcframwork build but i dont know how to change this.
Posted Last updated
.
Post not yet marked as solved
3 Replies
264 Views
I have an application made for iPhone and iPad with enabled capability to run natively on M1 Macs. When I try to resign it with an AdHoc profile: codesign --force --deep -s - MyApp.app Application can not be launched anymore with error: "MyApp.app" cannot be opened because the developer did not intend for it to run on this Mac. Contact the developer for support. Is there way to resign it without loosing an ability to run on M1 Mac? Thanks!
Posted
by ToyoApps.
Last updated
.
Post marked as solved
3 Replies
141 Views
Hello, I would like to know how I can sign a macOS app not developed on Xcode, is it possible to distribute on App Store an app not created on Xcode ? Thanks in advance
Posted Last updated
.
Post not yet marked as solved
2 Replies
228 Views
Hello! I am trying to build a CI pipeline for a safari browser extension. And in order to achieve this I am manually signing the .app. The file that creates problems is the .appex. From "extensionName.app/Contents/PlugIns/extenstionName Extension.appex". Not signing this file causes the notarization to flag the package as invalid. The order that I achieved the signing and caused the notarisation to work is this. (not actual signing request lines, I simplified them for easier readability) # Signing first all the .dylib files -timestamp --options runtime "extenstionName.app/Contents/Frameworks/*.dylib" # Then signing the binary from the appex --prefix=com.domain. --timestamp --options runtime "extenstionName.app/Contents/PlugIns/extenstionName Extension.appex/Contents/MacOS/extenstionName Extension" # Then signing the .app package --prefix=com.domain. --timestamp --options runtime "extenstionName.app/" # And at the end signing the .appex --prefix=com.domain. --timestamp --options runtime "extensionName.app/Contents/PlugIns/extensionName Extension.appex" If I do the signing this way the notarization works, and the .app is code signed and can be verified. The issue is that the extension does not load at all in safari, not even with Allow Unsigned Extensions enabled. And I can't find any way to debug this. Clicking Quit and Open Safari Extensions Preferences... does nothing, nothing appears inside the Safari Extension Preferences menu. I tried multiple combinations of signing order. Signing the .appex before the .app causes the code signature to not be valid at all. Do not sign the .appex at all causes the .app to be verified and signed but in safari you need to have unsigned extension enabled. And also the notarization fails throwing errors about the .appex that is not signed Not signing the binary from the .appex causes the notarization to fail throwing error that that binary is not signed. Also I tried to run the signed and notarized .app on a clean macOS computer, and it does not load into safari, the same that happens on the development computer.
Posted
by mihainsto.
Last updated
.