В экосистеме Apple сейчас так устроено, что для выпуска приложений iOS/macOS требуется получение сертификата, затем подпись кода и нотаризация подписи. Согласно документации, подпись кода гарантирует пользователям, что приложение получено из известного источника и не изменялось. Для получения и использования сертификатов требуется участие в программе Apple Developer Program.

Такая система удобна с точки зрения безопасности закрытой экосистемы Apple, но создаёт некоторые трудности для разработчиков.

Однако любые трудности на то и существуют, чтобы их преодолевать.

Подпись и нотаризация


В большинстве случаев для запроса и установки цифровых сертификатов используется Xcode.

Если посмотреть на реально используемые программные модули, то система подписи кода Apple довольно сложная: официальные инструменты codesign поддерживают ряд продвинутых функций, в том числе подпись пакетов с вложенной структурой, подпись DMG, инсталляторов .pkg и др. Нативная процедура подписи не полностью задокументирована, а опубликованный исходный код не полностью соответствует актуальным версиям инструментов.

Нужно заметить, что Apple имеет право в любой момент отозвать сертификат любого разработчика — и его софт перестанет работать на компьютерах или смартфонах. Например, такое однажды случилось с разработчиком программы Downie для скачивания видео с YouTube (на скриншотах вверху и внизу).



Apple крайне неохотно публикует исходники своих инструментов в репозитории Apple-FOSS. Например, около десяти лет назад опубликована часть кода SecurityFramework, но с тех пор обновления не произошло, репозиторий очень устарел. И там отсутствует код для нотаризации подписей через notarytool.

Кроме того, инструмент подписи кода Apple зависит от нативных библиотек Cocoa/OSX, таких как CoreFoundation, с которыми по факту опенсорсные инструменты работать не могут.

Поэтому создать современный аналог нативного codesign — крайне сложная задача, не говоря уже о нотаризации. Но нашлись разработчики, которые справились с ней.

Подпись приложений Apple на компьютерах Linux




Во-первых, есть малоизвестный инструмент ldid от Джея Фримана. Этот разработчик под ником saurik известен джейлбрейками iOS и проектом Сydia — альтернативным каталогом программного обеспечения для iOS. Очевидно, что «освобождённым» приложениям из этого каталога для установки на iPhone не требуется нотаризация подписи в компании Apple, а сам Джей Фриман не очень одобряет саму идею подписи программ, хотя был вынужден разработать такой инструмент для собственных нужд.

Так или иначе, но есть ldid и его форки и документация для ldid.

Для подписи приложений iOS под Linux также существует опенсорсная программа isign. Например, она может подойти в некоторых нестандартных ситуациях:

  • Необычные подписи (скажем, компания хочет выпускать сертификаты с использованием аппаратного модуля безопасности).
  • Распространение приложений iOS/macOS через сторонние каталоги. Это актуально в современных условиях, когда у некоторых компаний нет возможности публикации своих приложений в App Store.
  • Массовая публикация приложений в App Store под разными названиями для новых версий.

Apple Codesign


Недавно был разработан инструмент apple-codesign — полная реализация подписи приложений Apple на чистом Rust. Эта программа не имеет никаких внешних зависимостей и не требует для работы никаких проприетарных модулей. Она поддерживает все продвинутые функции нативных инструментов codesign и notarytool, включая подпись бинарников Mach-O, каталогов .app, архивов XAR, инсталляторов .pkg, дисковых образов DMG и др.

Как пишет разработчик, в последней версии его программа избавилась от инструмента Transporter для нотаризации. Это нативное Java-приложение Apple работало под macOS, Linux и Windows, связываясь c серверами Apple в процессе нотаризации подписи. Однако на конференции WWDC 2022 компания Apple представила программные интерфейсы Notary API, которые осуществляют процедуру чисто через API, принимая вызовы из любой программы. Во вспомогательном инструменте командной строки rcodesign всё взаимодействие с Notary API и заверение подписи производится одной командой в консоли:

rcodesign notary-submit

Таким образом, с помощью крейта apple-codesign теперь можно подписывать и заверять программы iOS/maсOS с любых компьютеров под Linux, Windows, macOS, BSD и пр. В принципе, с некоторыми затруднениями такое было возможно и раньше, но теперь этот барьер официально пал.

Последняя версия Apple Codesign 0.17.0 вышла 8 августа 2022 года.

Зачем нужны сторонние инструменты


Есть много разных причин для автоматической подписи приложений iOS/macOS под Linux и другими ОС. Чаще всего это нужно для конвейеров непрерывной интеграции (CI/CD) с автоматизацией сборки, как делают сервисы типа Fastlane.

Сейчас автоматизация сборки под Mac требует некоторых манипуляций с VM или покупки/взятия в аренду настоящего Mac. Если появляется возможность организовать CI просто под Linux, это кардинально упрощает инфраструктуру всей среды разработки. Правда, тесты и валидацию всё равно желательно проводить на настоящем железе Apple, но конкретно для подписи программ теперь не нужен компьютер Apple. Достаточно маленького контейнера под Linux. Это можно делать на тех же компьютерах, что и подпись кода для всех остальных платформ. Такой подход кажется более логичным, безопасным и удобным в долгосрочной поддержке.



Подробнее о сертификатах подписи кода на сайте GlobalSign

Комментарии (5)


  1. Aleksid1
    19.08.2022 08:34
    +1

    Э, все равно не улавливаю смысл. Для компиляции Mac приложения тоже ведь нужна macOS? Например ч пишу на FPC и он компилирует под Мак только на Мак. Логично здесь же и подписать и нотаризовать.


    1. alexac
      19.08.2022 11:47
      +2

      Формат Mach-O достаточно хорошо документирован, а инструменты для работы с ним опенсорсные и кроссплатформенные. Для сборки под macos/ios нужны файлы из SDK, который можно легко вытащить из xcode, но в остальном, если не использовать interface-builder, то ничего не мешает собирать код на других платформах. Если писать на go/rust, это уже работает из коробки, если писать на C/C++/Objective-C/Objective-C++, то с использованием llvm это потребует каких-то усилий на настройку, но в принципе тоже реализуемо.

      Плюс есть особые кейсы вроде игровых движков, когда создатель движка собирает код движка в бинарник, а для сборки игры нужно просто сложить вместе бинарники движка и архивы со скриптами и прочими ресурсами. А потом подписать. Например так устроена сборка игр на defold. Инструмент сборки там отлично справляется над тем, чтобы собрать приложение под mac на linux. А вот под ios отказывается, так как хочет работать с подписью.


    1. vassabi
      19.08.2022 12:07

      В свое время MarmaladeSDK компилировал бинарники под процессор (х86, арм, мипс), а потом линковал с загрузчиком, подписывал и собирал всё (бинарники и ресурсы) в приложение. Собственно поэтому там были портированы маковские ld и codesign.

      Это позволяло делать всё на Вин, включая и разработку и деплой (айтюнс есть под винду, можно даже залить приложение прямо оттуда, а если в режиме разработчика - то и просто самоподписанное)


    1. sgusev
      19.08.2022 16:53
      +1

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

      Проблема тут в том, что процесс создания конечного приложения выглядит так: компиляция кода в бинарники -> подпись -> упаковка в dmg/pkg (а на винде - ещё и повторная подпись результирующего exe файла инсталлера). Можно, конечно, просто собрать бинарники и отдать архив с ними с чистой совестью, пусть пакуют как хотят, нооо это только в идеальном мире. В реальной жизни заказчику нужно готовое приложение "под ключ", и его не волнуют все эти технарские термины вроде CI/CD.

      Поэтому иногда приходится делать следующие костыли: собираем на своих машинах -> аплоадим заказчику на закрытый сервер, где оно автоматически подписывается -> принимаем в ответ подписанные бинари и пакуем их в инсталлер. И вот тут уже было бы очень полезно иметь независимые инструменты подписи, чтобы не обязывать заказчика иметь мак на принимающей стороне. Понятно, что компании, у которых есть деньги на брендированное приложение, скорее всего имеют возможность купить себе отдельный мак для подписи бинарников раз в месяц, но тем не менее.


    1. cepera_ang
      21.08.2022 08:29

      Кросс-компиляция же. Автор упомянутого тула разрабатывал его специально для того, чтобы унифицировать релизы на все платформы. Грубо говоря, раньше у тебя собирались пакеты под линукс и винду на каком-нибудь github actions, а под мак нужно было пойти и ещё вручную подписать. А сейчас можно всё сразу собирать и подписывать в одном месте.