Notarization for macOS 10.14.5+/ru

From Free Pascal wiki
Jump to navigationJump to search

English (en) русский (ru)

macOSlogo.png

Эта статья относится только к macOS.

См. также: Multiplatform Programming Guide


Обзор

Начиная с macOS 10.14.5 (Mojave), программное обеспечение, подписанное новым сертификатом разработчика Apple, и все новые или обновленные расширения ядра должны быть нотариально заверены для запуска. Начиная с macOS 10.15 (Catalina), все программное обеспечение, созданное после 1 июня 2019 года, и код, подписанный сертификатом разработчика Apple, необходимо нотариально заверить. Нотариальное заверение не требуется для программного обеспечения, распространяемого через Apple App Store, поскольку процесс отправки в App Store уже включает эквивалентные проверки безопасности.

Нотариальное заверение разработано Apple, чтобы дать пользователям больше уверенности в том, что программное обеспечение, подписанное разработчиками Apple, было проверено Apple на наличие вредоносных компонентов. Нотариальное заверение - это не проверка приложения. Нотариальная служба Apple - это автоматизированная система, которая сканирует программное обеспечение на наличие вредоносного содержимого, проверяет наличие проблем с подписью кода и возвращает результаты. Если проблем нет, нотариальная служба генерирует удостоверение для установки программного обеспечения; нотариальная служба также публикует это удостоверение в Интернете, где его может найти Gatekeeper (прим.перев.: букв. привратник).

Когда пользователь впервые устанавливает или запускает программное обеспечение, наличие удостоверения (онлайн или прикрепленного к исполняемому файлу) сообщает Gatekeeper, что Apple нотариально заверила программное обеспечение. Затем Gatekeeper помещает описательную информацию в диалоговое окно первоначального запуска, чтобы помочь пользователю сделать осознанный выбор, запускать ли приложение.

Light bulb  Примечание: Даже если приложение не было нотариально заверено, его все равно можно запустить, щелкнув приложение, удерживая клавишу Control, или щелкнув правой кнопкой мыши для вызова контекстного меню, выбрав «Открыть» - см. диалоговое "обходное" окно Gatekeeper в галерее ниже.

Подписание кода приложения без нотариального заверения - теперь совершенно бессмысленное упражнение, если только вы не распространяете свое приложение только через App Store.

Диалоговые окна Gatekeeper

Требования к нотариальному заверению

Для нотариального заверения требуются инструменты командной строки Xcode от Xcode 10 или новее. Для создания нового приложения для нотариального заверения требуется macOS 10.13.6 или новее. Для прикрепления приложения требуется macOS 10.12 или новее.

Нотариальная служба Apple требует от вас:

  • Включения подписывания кода для всех распространяемых вами исполняемых файлов.
  • Включения возможности заверения через Hardened Runtime для вашего приложения и целей командной строки.
  • Использования приложения «Developer ID», расширения ядра или сертификата установщика для подписи кода.
  • Включения безопасной метки времени в свою подпись для подписи кода (включения параметра --timestamp при запуске инструмента кодовой подписи).
  • Не включать право com.apple.security.get-task-allow со значением, равным любому варианту истинного. Если в вашем программном обеспечении размещаются сторонние плагины и требуется это право для отладки плагина в контексте исполняемого файла хоста, см. Avoid the Get-Task-Allow Entitlement.
  • Ссылки на SDK для macOS 10.9 или новее.

3 сентября 2019 года Apple объявила, что до января 2020 года разработчики могут нотариально заверить новые версии приложений, даже если они не были заверены через hardened или полностью соответствуют обычным требованиям. Позднее этот срок был продлен до 3 февраля 2020 года. Вышеуказанные требования к нотариальному удостоверению теперь действуют в полной мере.

Заявление Apple от 23 декабря 2019 г.

В июне мы объявили, что все программное обеспечение Mac, распространяемое за пределами Mac App Store, должно быть нотариально заверено Apple, чтобы оно могло работать по умолчанию на macOS Catalina. В сентябре мы временно скорректировали предварительные условия нотариального заверения, чтобы упростить этот переход и защитить пользователей macOS Catalina, которые продолжают использовать более старые версии программного обеспечения. Начиная с 3 февраля 2020 года, все представленное программное обеспечение должно соответствовать предварительным требованиям для нотариального заверения.

Если вы еще не сделали этого, загрузите программное обеспечение в нотариальную службу и просмотрите журнал разработчика на наличие предупреждений. Эти предупреждения станут ошибками с 3 февраля и должны быть исправлены, чтобы ваше программное обеспечение было нотариально заверенным. Программное обеспечение, нотариально заверенное до 3 февраля, по умолчанию будет продолжать работать на macOS Catalina.

Напоминаем, что все пакеты установщика должны быть подписаны, поскольку они могут содержать исполняемый код. Образы дисков не нужно подписывать, хотя их подписание может помочь вашим пользователям проверить их содержимое.

Нотариальное заверение заявки

В этих инструкциях предполагается, что вы выполнили другие подготовительные шаги: подписание кода приложения, реализованное в усиленной среде выполнения, подписание кода установщика pkg (если он у вас есть) и т.д.

Вы не можете выгрузить пакет .app непосредственно в нотариальную службу, вам необходимо создать сжатый архив, содержащий приложение, или вы можете поместить приложения, расширения ядра и другое программное обеспечение в контейнер, например образ диска, и нотариально заверить контейнер. Нотариальная служба принимает образы дисков (формат UDIF), подписанный установщиком плоских пакетов, и ZIP-архивы. Он также обрабатывает вложенные контейнеры, например пакеты внутри образа диска.


Шаг 1 - Создание образа диска

Создайте образ диска, открыв Терминал и выполнив следующую команду:

hdiutil create -volname MyApp -srcfolder /path/to/folder -ov -format UDBZ MyApp.dmg

Step 2 - Code sign the disk image

Code sign the disk image by opening a Terminal and running the following command:

codesign -s "Developer ID Application: Your Name (Team ID)" --timestamp MyApp.dmg


Step 3 - Generate an app-specific password

To generate an app-specific password, refer to this Apple Support article. Note: this is a password that will be specific to the notarization application (xcrun altool) and not to the application being notarized. You therefore only need to do this once, but make sure you copy the generated password and save it somewhere.

Note-icon.png

Подсказка: Save the password to your keychain with:

xcrun altool -u "<your email>" -p "<app-specific pwd>" --store-password-in-keychain-item "<name for pwd>"

and then you can use "@keychain:<name for pwd>" instead of "<app-specific pwd>" in the following commands.

Step 4 - Upload the disk image to the notary service

Light bulb  Примечание: When you notarize the container disk image, altool also notarizes the application inside, so you can skip the step of notarizing the application itself.


Upload the disk image file to the Apple notary service by opening a Terminal and running the following command:

xcrun altool --notarize-app --primary-bundle-id "<your identifier>" -u "<your email>" -p "<app-specific pwd>" -t osx -f /path/to/MyApp.dmg

The primary-bundle-id helps you keep track of automated correspondence from the notarization service. The value you give doesn’t need to match the bundle identifier of the submitted app or have any particular value. It only needs to make sense to you. The notarization service includes the value whenever it emails you regarding the given altool submission.

If the upload is successful you should receive output similar to the following:

No errors uploading 'MyApp.dmg'.
RequestUUID = 3af4e56f-162b-75bc-827f-7233f92bf20c


Step 5 - Check the notarization process

The notarization process generally takes less than an hour, so you may want to check its progress from time to time by opening a Terminal and running the following command:

xcrun altool --notarization-history 0 -u "<your email>" -p "<app-specific pwd>"

When the notarization process completes successfully the above command will return information similar to the following:

Notarization History - page 0

Date                      RequestUUID                          Status  Status Code Status Message   
------------------------- ------------------------------------ ------- ----------- ---------------- 
2019-12-08 06:24:03 +0000 3af4e56f-162b-75bc-827f-7233f92bf20c success 0           Package Approved 

Next page value: 1575786243000

You should also receive an email from Apple similar to the following for a successful notarization:

Dear <First_Name>,

Your Mac software has been notarized. You can now export this software and distribute it directly to users.

Bundle Identifier: com.example.MyApp.001
Request Identifier: 3af4e56f-162b-75bc-827f-7233f92bf20c

For details on exporting a notarized app, visit Xcode Help or the notarization guide.

Best Regards,
Apple Developer Relations


Step 6 - Staple the ticket to the disk image

The notarization process produces a ticket that tells Gatekeeper that your application is notarized. After notarization completes successfully, the next time any user attempts to run your application on macOS 10.14 or later, Gatekeeper will find the ticket online. This includes users who downloaded your application before notarization.

After step 5 receives the "Package Approved" status message, you should also attach the ticket to the disk image file using the stapler tool, so that future distributions include the ticket. This ensures that Gatekeeper can find the ticket even when a network connection is not available.

To staple the ticket to the disk image file, open a Terminal and run the following command:

xcrun stapler staple /path/to/MyApp.dmg

If the command completes successfully, the output should be similar to:

Processing: /Path/to/MyApp.dmg
Processing: /Path/to/MyApp.dmg
The staple and validate action worked!


Step 7 - Verify notarization of the disk image

To verify the notarization of the disk image, open a Terminal and run the following command:

spctl -a -vv -t install MyApp.dmg

A successful verification of the notarization process should produce output similar to the following:

MyApp.dmg: accepted
source=Notarized Developer ID
origin=Developer ID Application: <Developer Name> (<TEAM_ID>)


Step 8 - Verify notarization of the application

To verify the notarization of the application, install the application, open a Terminal and run the following command:

spctl -a -vv /Applications/MyApp.app

A successful verification of the notarization process should produce output similar to the following:

/Applications/MyApp.app: accepted
source=Notarized Developer ID
origin=Developer ID Application: <Developer Name> (<TEAM_ID>)

Important: test the application by putting it in the Applications directory. It's treated differently by the Gatekeeper when in the "installed" location.

Alternatively, the Apple-recommended way to verify the notarization of an application is to open a Terminal and run the following command:

xcrun stapler validate MyApp.app

A successful verification of the notarization process should produce output similar to the following:

Processing: MyApp.app
The validate action worked!

Notarizing a command line tool

Command line tools can be code signed, but they cannot be easily notarized because they do not have an Application Bundle and a standalone Info.plist property list file. You can relatively easily insert an Info.plist file in your command line tool executable.

Inserting an Info.plist in a command line executable

Here is a template that you can customise for your command line utility. I extracted it from a command line utility executable written in C named "simplereach" which I built with Xcode 11.3.1 on Mojave after enabling the "Create Info.plist Section in Binary" under the "Packaging" options (I have omitted the unnecessary Xcode-related build info from it).

<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>BuildMachineOSBuild</key>
	<string>18G8022</string>
	<key>CFBundleDevelopmentRegion</key>
	<string>English</string>
	<key>CFBundleDocumentTypes</key>
	<array>
		<dict>
			<key>CFBundleTypeOSTypes</key>
			<array>
				<string>fold</string>
				<string>disk</string>
				<string>****</string>
			</array>
		</dict>
	</array>
	<key>CFBundleExecutable</key>
	<string>simplereach</string>
	<key>CFBundleIdentifier</key>
	<string>com.mycompany.simplereach</string>
	<key>CFBundleInfoDictionaryVersion</key>
	<string>6.0</string>
	<key>CFBundleName</key>
	<string>simplereach</string>
	<key>CFBundlePackageType</key>
	<string>APPL</string>
	<key>CFBundleShortVersionString</key>
	<string>1.0</string>
	<key>CFBundleSupportedPlatforms</key>
	<array>
		<string>MacOSX</string>
	</array>
	<key>CFBundleVersion</key>
	<string>1</string>
	<key>LSMinimumSystemVersion</key>
	<string>10.14</string>
</dict>
</plist>

You will need to modify a few key strings in the above file. Substitute your own:

  • BuildMachineOSBuild string can be obtained from a Terminal with the command sw_vers. The "18G8022" strong is for Mojave 10.14.6.
  • CFBundleDevelopmentRegion string if it is not "English".
  • CFBundleExecutable string with your utility name.
  • CFBundleIdentifier string (conventionally your domain name in reverse followed by utility name; feel free use anything unique).
  • CFBundleName string (use the same value as for CFBundleExecutable).
  • CFBundleShortVersionString string with your version number.
  • LSMinimumSystemVersion string with the minimum macOS version on which your utility will run.

You can then insert the Info.plist file into your application by telling the linker to add it as a __TEXT section named __info_plist:

fpc -k"-sectcreate __TEXT __info_plist Info.plist" my_utility.pas

To check whether it has been successfully inserted you can run the following command in a Terminal:

otool -X -v -s __TEXT __info_plist my_utility

Signing a command line executable

Now that the Info.plist file has been inserted in the executable, you are ready to code sign it by executing the following commands in a Terminal:

cd /path/to/my_utility
mkdir bin
mv my_utility bin/
codesign -f --strict --timestamp --options=runtime -s "Developer ID Application: YOUR NAME (TEAM_ID)" bin/my_utility

It is critical that you create the bin directory and move your utility to it before signing. Failure to do so will result in a _CodeSignature directory being created which is not appropriate for a command line utility and the notarisation process will fail.

To verify this was successful you can run the following command in a Terminal:

codesign -vv bin/my_utility

If code signing was successful, the output should be something similar to:

my_utility: valid on disk
my_utility: satisfies its Designated Requirement 

Submitting a command line executable for notarization

As you cannot notarize a bare executable, you need to incorporate it into a container (.dmg - Disk Image, .pkg - Installer Package, or a ZIP archive file). A ZIP archive is the simplest so in a Terminal execute the following command:

zip my_utility.zip bin/my_utility

You are now ready to upload your command line utility to Apple's servers for notarization. In a terminal execute the following command:

xcrun altool --notarize-app --primary-bundle-id "<your identifier>" -u "<your email>" -p "<app-specific pwd>" -t osx -f my_utility.zip

If you do not already have an app specific password, see above for how to generate one.

The primary-bundle-id helps you keep track of automated correspondence from the notarization service. The value you give doesn’t need to match the bundle identifier of the submitted app or have any particular value. It only needs to make sense to you. The notarization service includes the value whenever it emails you regarding the given altool submission.

If the upload is successful you should receive output similar to the following:

No errors uploading 'my_utility'.
RequestUUID = 3af4e56f-162b-75bc-827f-7233f92bf20c

Checking the notarization progress

The notarization process generally takes from 10 to 15 minutes, so you may want to check its progress from time to time by running the following command from a Terminal:

xcrun altool --notarization-history 0 -u "<your email>" -p "<app-specific pwd>"

When the notarization process completes successfully the above command will return information similar to the following:

Notarization History - page 0
Date                      RequestUUID                          Status  Status Code Status Message   
------------------------- ------------------------------------ ------- ----------- ---------------- 
2021-04-22 10:55:03 +0000 3af4e56f-162b-76bc-826f-7263f92bf20c success 0           Package Approved 
Next page value: 1575786243000

You should also receive an email from Apple similar to the following for a successful notarization:

Dear <First Name>,
Your Mac software has been notarized. You can now export this software and distribute it directly to users.
Bundle Identifier: 
Request Identifier: 70dbe301-d3a7-4931-9ec3-61c5cc80573c
For details on exporting a notarized app, visit Xcode Help or the notarization guide. 
Best Regards,
Apple Developer Relations

In case of a notarization failure, consult Troubleshooting below for help.

Verifying notarization of a command line executable

To verify the notarization of a command line tool, open a Terminal and run the following command:

spctl -a -t open --context context:primary-signature -vv my_utility 

A successful verification of a properly notarized command line executable should produce output similar to the following:

my_utility: accepted
source=Notarized Developer ID
origin=Developer ID Application: Your Name (Z9HBGNDZZ9)

Troubleshooting

Notarization upload process

If the notarisation upload process does not go well, you should be able to find a compressed log file in your temporary directory which may shed some light on what happened. You can view it by opening a Terminal and running the following commands (substitute the name of your log file which includes your application bundle-id):

  cd ${TMPDIR}
  gzcat c51ca05f-cf49-405f-be57-26873faab5f6_3073718126753816760org.sentry.myapp-20191231004646-273.itmsp6022059143057318377.log

which, for a successful notarization upload, should look similar to:

 [2019-12-31 19:46:46 AEDT] <main>  INFO: Starting upload for packageName: org.sentry.myapp-20191231004646-273.itmsp
 [2019-12-31 19:46:46 AEDT] <main>  INFO: Thread Pool Configuration: {processors=12, perCoreThreadMultiplier=1.65, coreThreads=6, maxThreads=14, minConnections=6, maxConnections=13, rateLimit=100000000000 KBs}
 [2019-12-31 19:46:46 AEDT] <main>  INFO: Reservation CPUSource113/v4/93/41/ce/9341ce96-e7bc-2577-eaac-4528c888a70d/metadata.xml created for file: (metadata.xml), part count:(1), file size: (538)
 [2019-12-31 19:46:46 AEDT] <main>  INFO: Reservation CPUSource113/v4/93/41/ce/9341ce96-e7bc-2577-eaac-4528c888a70d/MyApp_31122019.dmg created for file: (MyApp_31122019.dmg), part count:(1), file size: (1400933)
 [2019-12-31 19:46:46 AEDT] <RLT-002>  INFO: Starting upload for reservation: (CPUSource113/v4/93/41/ce/9341ce96-e7bc-2577-eaac-4528c888a70d/metadata.xml) file: (metadata.xml/1) size: 538
 [2019-12-31 19:46:46 AEDT] <RLT-003>  INFO: Starting upload for reservation: (CPUSource113/v4/93/41/ce/9341ce96-e7bc-2577-eaac-4528c888a70d/myapp_31122019.dmg) file: (MyApp_31122019.dmg/1) size: 1400933
 [2019-12-31 19:46:47 AEDT] <RLT-002>  INFO: Finished part upload for: (metadata.xml/1) 2.91 KB/s in 0 seconds
 [2019-12-31 19:46:47 AEDT] <RLT-002>  INFO: Finished upload for reservation: (CPUSource113/v4/93/41/ce/9341ce96-e7bc-2577-eaac-4528c888a70d/metadata.xml) file: (metadata.xml)
 [2019-12-31 19:46:47 AEDT] <pool-8-thread-1>  INFO: Reservation committed: (CPUSource113/v4/93/41/ce/9341ce96-e7bc-2577-eaac-4528c888a70d/metadata.xml) file: (metadata.xml)
 [2019-12-31 19:46:49 AEDT] <RLT-003>  INFO: Finished part upload for: (MyApp_31122019.dmg/1) 781.33 KB/s in 1 second
 [2019-12-31 19:46:49 AEDT] <RLT-003>  INFO: Finished upload for reservation: (CPUSource113/v4/93/41/ce/9341ce96-e7bc-2577-eaac-4528c888a70d/MyApp_31122019.dmg) file: (MyApp_31122019.dmg)
 [2019-12-31 19:46:49 AEDT] <main>  INFO: Waiting on reservation commit(s) to finish.
 [2019-12-31 19:46:49 AEDT] <pool-8-thread-1>  INFO: Reservation committed: (CPUSource113/v4/93/41/ce/9341ce96-e7bc-2577-eaac-4528c888a70d/MyApp_31122019.dmg) file: (MyApp_31122019.dmg)
 [2019-12-31 19:46:49 AEDT] <pool-8-thread-1>  INFO: All reservation commit(s) finished.
 [2019-12-31 19:46:49 AEDT] <main>  INFO: 456.36 KB/s in 3 seconds

Notarization process failures

If the when you check you find that the notarization process has failed. For example:

Date                      RequestUUID                          Status  Status Code Status Message   
------------------------- ------------------------------------ ------- ----------- ---------------- 
2020-02-29 13:54:08 +0000 fa2e5d79-cba0-469d-bb27-859a8f081821 invalid 2           Package Invalid  

You can retrieve the URL for the notarization log file with the command:

xcrun altool --notarization-info <RequestUUID> -u "<your email>" -p "<app-specific pwd>"

which should yield information similar to the following:

No errors getting notarization info.

          Date: 2020-02-29 13:54:08 +0000
          Hash: 1b08ea5cdf97eb6fed9b959a549d4b325eb5e90f16538139a29a83f75609d87b
    LogFileURL: https://osxapps-ssl.itunes.apple.com/itunes-assets/[...]
   RequestUUID: fa2e5d79-cba0-469d-bb27-859a8f081821
        Status: invalid
   Status Code: 2
Status Message: Package Invalid

You can then cut and paste the LogFileURL into your web browser and retrieve the notarization process log file which will look something like this:

{
  "logFormatVersion": 1,
  "jobId": "fa2e5d79-cba0-469d-bb27-859a8f081821",
  "status": "Invalid",
  "statusSummary": "Archive contains critical validation errors",
  "statusCode": 4000,
  "archiveFilename": "test.dmg",
  "uploadDate": "2020-02-29T13:54:08Z",
  "sha256": "1b08ea5cdf97eb6fed9b959a549d4b325eb5e90f16538139a29a83f75609d87b",
  "ticketContents": null,
  "issues": [
    {
      "severity": "error",
      "code": null,
      "path": "test.dmg/MyApp.app/Contents/MacOS/MyApp",
      "message": "The executable does not have the hardened runtime enabled.",
      "docUrl": null,
      "architecture": "x86_64"
    }
  ]
}

In the above failure case, it was because the executable had not been hardened.

It is also worthwhile mentioning that it is always worth retrieving the notarization log file to check for warnings which are not yet errors so that you can fix them before they do become errors which prevent successful notarization.

Here is an example of a notarization process log from a successful notarization:

{
  "logFormatVersion": 1,
  "jobId": "fa2e5d79-cba0-469d-bb27-859a8f081822",
  "status": "Accepted",
  "statusSummary": "Ready for distribution",
  "statusCode": 0,
  "archiveFilename": "test.dmg",
  "uploadDate": "2020-03-01T01:50:55Z",
  "sha256": "1945554c24da3bb1d587b7c9f968dcbb925b726f2f663b816301928c06593dd9",
  "ticketContents": [
    {
      "path": "test.dmg",
      "digestAlgorithm": "SHA-256",
      "cdhash": "1d4d033edbecc2baf7ff8ce0fa16691be990595f"
    },
    {
      "path": "test.dmg/MyApp.app",
      "digestAlgorithm": "SHA-256",
      "cdhash": "7f9d54e76f25807e2b425a09684aa8cb54dcd17f",
      "arch": "x86_64"
    },
    {
      "path": "test.dmg/MyApp.app/Contents/MacOS/MyApp",
      "digestAlgorithm": "SHA-256",
      "cdhash": "7f9d54e762c7907e2b425a09684aa8cb54dcd17f",
      "arch": "x86_64"
    },
    {
      "path": "test.dmg/MyApp.app/Contents/Resources/MyApp.help",
      "digestAlgorithm": "SHA-256",
      "cdhash": "b544a32a216578e7805ca93b968377cdd92f7ec6",
      "arch": "i386"
    },
    {
      "path": "test.dmg/MyApp.app/Contents/Resources/MyApp.help",
      "digestAlgorithm": "SHA-256",
      "cdhash": "b544a32a216578e7805ca93b968377cdd92f7ec6",
      "arch": "x86_64"
    },
    {
      "path": "test.dmg/MyApp.app/Contents/Resources/MyApp.help",
      "digestAlgorithm": "SHA-256",
      "cdhash": "b544a32a216578e7805ca93b968377cdd92f7ec6",
      "arch": "x86_64h"
    }
  ],
  "issues": null
}

Notarization check failures

If the notarization process succeeds, but when you check whether your application is properly notarized and it does not pass the notarization check successfully, you can use the Console.app to inspect the log files for information about the rejection (after trying to launch the blocked application). Be aware you should open the Console.app before trying to open your blocked application, otherwise not all messages may be logged. You should choose your device in the left sidebar of the Console.app and check for the process XprotectService in the logs.

See also

External links