Получение бесплатного сертификата разработчика для проекта с открытым исходным кодом от SignPath

от автора

Прочитать о сертификатах (Code signing) можно тут.

На Хабре уже рассказывалось о бесплатной (уже давно не бесплатной) возможности подписать свои открытые проекты: https://habr.com/ru/articles/242267/.

Компания SignPath GmbH предлагает бесплатную сертификацию проектов с открытым исходным кодом (https://about.signpath.io/product/open-source). Есть возможность подписывать как исполняемые файлы Windows, так и контейнеры Docker. Сборка проекта должна выполняться с помощью GitHub Actions. Вся документация доступна по адресу https://about.signpath.io/documentation/getting-started.

38d6c5773a6d0b4c63819412d817898c.png

38d6c5773a6d0b4c63819412d817898c.png

Я прошёл этот путь и вот как это было.

Проект

О своём проекте я уже немного рассказывал на Хабре.

Весь код написан на Python с использованием PySide6 и другими пакетами. Для сборки под Windows используется PyInstaller и Nuitka (с Nuitka работает быстрее, но иногда бывают странные ошибки, поэтому пока не отказался от PyInstaller), а инсталляционный пакет собирается с помощью Inno Setup. Весь процесс сборки настроен на GitHub Actions.

При запуске инсталлятора или приложения Windows выдает всем знакомое предупреждение:

ae21cbb7750e0a68aadf04ddea553acd.png

ae21cbb7750e0a68aadf04ddea553acd.png

Чтобы избавится от него, исполняемый файл должен быть подписан доверенным сертификатом разработчика. Большинство сертификационных центров требуют оплату, но есть вариант получить подпись бесплатно.

Регистрация

Для того чтобы получить бесплатный сертификат необходимо отправить запрос на почту oss-support@signpath.org. Я написал буквально пару предложений с описанием и ссылкой на проект.
Через пару дней пришла форма в файле Excel. Её нужно заполнить и отправить обратно. Самым интересным был пункт Репутация:

Опишите, как мы можем проверить, что ваш проект используется и заслуживает доверия.
Предоставьте источники и ссылки, включая
* Обзоры в СМИ
* Статьи в блогах
* Статьи Википедии на других языках (см. ниже для английского), Softpedia и т. д.
* Данные об использовании, такие как количество загрузок, форков или зависимостей
* Аналитика, такая как GitHub Insights
* Доказательство права собственности на товарный знак, если вы используете зарегистрированное название
Если доступно, мы также рассмотрим статью в Википедии на английском языке и OpenHub, а также данные сообщества, такие как GitHub Insights.

Спустя 2 недели проект был зарегистрирован о чем пришло два письма с уведомлениями о привязке почты и регистрации организации. Получив подтверждение регистрации не спешите подтверждать, видимо какие-то проблемы с синхрониpацией, мне удалось попасть в аккаунт только часов через 8 причём через Google аккаунт моей почты.

Никакой идентификации личности, проверки банковских карт не проводится.

SignPath предоставляет два сертификата: тестовый и сертификат выпуска (release sertificate). Тестовый сертификат (само-подписанный и не является доверенным) предназначен для настройки инфраструктуры и дальнейшего использования для тестовых сборок. Сертификат выпуска при регистрации не активен — имеет статус CSR PENDING. Для его активации необходимо выполнить настройку сборки проекта с тестовым сертификатом и дождаться «завершения внутреннего аудита безопасности» (в чем он заключается осталось загадкой).

Настройка GitHub Actions

Подписывать артефакты проекта можно как вручную загружая через сайт (доступно только для тестового сертификата), так и интегрировав процесс подписания в CI, например GitHub Actions или AppVeyor.

В этом разделе для большей наглядности я приведу пример для простого гипотетического приложения, собирающегося скриптом build.bat и состоящего из единственного исполняемого exe-файла. Конфигурация процесса сборки, перед добавлением шагов подписи, будет выглядеть следующим образом:

on:# Запускать процесс сборки при каждом выполнении git push   push:  jobs:   build:     runs-on: windows-latest     steps:     - name: Checkout repository       uses: actions/checkout@v4     - name: Build       run: build.bat# Запуск скрипта сборки     - name: Upload artifact       id: build# Этот ID будет использоваться на шаге подписания       uses: actions/upload-artifact@v4       with:         name: my_program         path: my_program.exe# Путь и имя файла - результат сборки 

Для интеграции с GitHub Actions необходимо получить API токен для CI. Для этого на странице Users and Groups необходимо выбрать пользователя CI builds и сгенерировать токен. Полученный токен добавляем в секреты репозитория GitHub как SIGNPATH_API_TOKEN (Settings — Secrets and variables — Actions — Repository secrets).

Так же для настройки сборки на сайте SignPath необходимо найти Organization ID (на странице организации), Project slug (на странице проекта, по умолчанию совпадает с названием проекта) и Signing policy (на странице проекта, по умолчанию test-signing и release-signing).

Отправить файл на сертификацию можно только из артефактов сборки (в примере выполняется на шаге Upload artifact). Артефакты GitHub загружаются в zip-архиве, а SignPath, по умолчанию, работает только с исполняемыми файлами. Поэтому необходимо добавить конфигурацию описывающую артефакт. В приведенном примере артефакт состоит из zip-архива, содержащего единственный exe-файл. Чтобы добавить конфигурацию артефакта необходимо на странице проекта в разделе Artifact Configurations нажать кнопку Add. На открывшейся странице ввести название новой конфигурации (в примере это test-zip), у поля Artifact configuration нажать кнопку Customize или выбрать Zip archive + sign nested files и ввести следующую конфигурацию:

<?xml version="1.0" encoding="utf-8" ?> <artifact-configuration xmlns="http://signpath.io/artifact-configuration/v1">   <!-- Define that the uploaded artifact is a ZIP file -->   <zip-file>     <pe-file-set>       <!-- Inside this uploaded ZIP file sign three PE files with Authenticode            (PE = Portable Executable, e.g., .exe or .dll file) -->       <include path="*.exe" />       <for-each>         <authenticode-sign />       </for-each>     </pe-file-set>   </zip-file> </artifact-configuration>
01660145ae1be4495cdf8f8682ceed64.png

01660145ae1be4495cdf8f8682ceed64.png

SignPath позволяет подписывать и внутренности MSI-пакетов, достаточно описать структуру пакета в конфигурации артефакта.

После этого нужно добавить шаг подписания в процесс сборки со следующим действием (action) https://github.com/SignPath/github-action-submit-signing-request:

    - name: Signing       uses: signpath/github-action-submit-signing-request@v1       with:         api-token: '${{ secrets.SIGNPATH_API_TOKEN }}'         organization-id: '3b087850-3844-4d25-8407-cf81e731f8d1'         project-slug: 'open-numismat'         signing-policy-slug: 'test-signing'         artifact-configuration-slug: 'test-zip'         github-artifact-id: '${{steps.upload.outputs.artifact-id}}'         output-artifact-directory: .# Результат заменит исходный файл         wait-for-completion: true

Этот шаг должен выполняться после шага с выгрузкой артефакта — Upload artifact в нашем примере.

Это действие отправляет артефакт в SignPath где он подписывается и результат загружается обратно. Есть ограничение на загрузку артефактов на проверку — 4Гб в месяц. Обратите внимание, что в SignPath отправляется zip-архив, а когда результат скачивается обратно он распаковывается автоматически по указанному в output-artifact-directory пути.

После шага подписи полученный подписанный файл вновь загружаем в артефакты:

    - name: Upload signed       uses: actions/upload-artifact@v4       with:         name: my_program-signed         path: my_program.exe 

Далее следующими шагами артефакты можно загрузить в релиз.

Получившаяся минимальная конфигурация процесса сборки будет выглядеть так:

on:# Запускать процесс сборки при каждом выполнении git push   push:  jobs:   build:     runs-on: windows-latest     steps:     - name: Checkout repository       uses: actions/checkout@v4     - name: Build       run: build.bat# Запуск скрипта сборки     - name: Upload artifact       id: build# Этот ID используется на шаге Signing       uses: actions/upload-artifact@v4       with:         name: my_program         path: my_program.exe# Путь и имя файла - результат сборки     - name: Signing       uses: signpath/github-action-submit-signing-request@v1       with:         api-token: '${{ secrets.SIGNPATH_API_TOKEN }}'         organization-id: '3b087850-3844-4d25-8407-cf81e731f8d1'         project-slug: 'open-numismat'         signing-policy-slug: 'test-signing'         artifact-configuration-slug: 'test-zip'         github-artifact-id: '${{steps.upload.outputs.artifact-id}}'         output-artifact-directory: .# Результат заменит исходный файл         wait-for-completion: true     - name: Upload signed       uses: actions/upload-artifact@v4       with:         name: my_program-signed         path: my_program.exe 

Теперь можно запустить тестовую сборку (в данном случае запустится сразу после выполнения git push). В логе сборки процесс подписания тестовым сертификатом выглядит так:

Submitting the signing request to SignPath CI connector... SignPath signing request has been successfully submitted The signing request id is 29add6f6-d0c7-48c7-963d-3e1f7a8853c9 You can view the signing request here: https://app.signpath.io/Web/3b087850-3844-4d25-8407-cf81e731f8d1/SigningRequests/29add6f6-d0c7-48c7-963d-3e1f7a8853c9 Checking the signing request status... The signing request status is InProgress, which is not a final status; after a delay, we will check again... Next check in a few seconds Signing request status is Completed Signed artifact url https://app.signpath.io/API/v1/3b087850-3844-4d25-8407-cf81e731f8d1/SigningRequests/29add6f6-d0c7-48c7-963d-3e1f7a8853c9/SignedArtifact The signed artifact is being downloaded from SignPath and will be saved to D:\a\open-numismat\open-numismat\dist\OpenNumismat Going to download signed artifact The signed artifact has been successfully downloaded from SignPath and extracted to D:\a\open-numismat\open-numismat\dist\OpenNumismat

Поскольку я использую Nuitka и PyInstaller и упаковываю результат в zip-архив для портативной версии и в инсталлятор с помощью Inno Setup, то мой вариант несколько сложнее. Перед упаковкой Inno Setup отправляю основной exe-файл на сертификацию, после получения упаковываю в инсталлятор и отправляю получившийся инсталлятор на сертификацию еще раз.

Ошибки с которыми я столкнулся

Error: Could not authorize against SignPath API. Trusted build system cannot be used in conjunction with an interactive user.

или

Error: Only runners in the groups «GitHub Actions» are allowed.

Использован SignPath токен обычного пользователя (interactive user), а не пользователя CI.

Другая ошибка:

There is no signing policy with slug ‘<…>’ in the project with slug ‘<…>’.

Неверные значения slug — вместо значения Signing policy указал Sertificate slug.

Error: The signing request is not completed. The final status is «Failed»

В случае этой ошибки искать причину нужно на сайте SignPath в разделе Signing Requests.

Сертификат выпуска

После того как все заработало с тестовым сертификатом я написал в поддержку, что у меня все работает и как бы мне получить доверенный сертификат выпуска. Через пару дней получил не очень внятный ответ: «Есть ли у вас в настоящее время на рассмотрении CSR? Если да, дайте нам ответ, чтобы мы могли заказать сертификат продукта». Написал подтверждение, что у меня уже есть сертификат выпуска в состоянии «CSR PENDING». На это получил ответ, что в течении недели я получу свой сертификат выпуска. И через пару часов получил письмо о том, что мой сертификат готов. Не могу сказать, что в этой процедуре было лишним, но в конечном итоге я увидел свой сертификат выпуска на сайте.

a0a9cec43739733d4dbc5dcd51fa3a21.png

a0a9cec43739733d4dbc5dcd51fa3a21.png

После этого обновил значение поле signing-policy-slug в шаге Signing конфигурации процесса сборки и запустил сборку на GitHub.

Подпись сертификатом выпуска требует ручного подтверждения. Поэтому процесс сборки приостановится на шаге Signing, а в логе сборки появятся следующие строки:

Submitting the signing request to SignPath CI connector... SignPath signing request has been successfully submitted The signing request id is 220a33ea-9fc9-4b53-b3b4-2bc176b4e5e2 You can view the signing request here: https://app.signpath.io/Web/3b087850-3844-4d25-8407-cf81e731f8d1/SigningRequests/220a33ea-9fc9-4b53-b3b4-2bc176b4e5e2 Checking the signing request status... The signing request status is InProgress, which is not a final status; after a delay, we will check again... Next check in a few seconds The signing request status is WaitingForApproval, which is not a final status; after a delay, we will check again... Next check in a few seconds The signing request status is WaitingForApproval, which is not a final status; after a delay, we will check again... Next check in a minute

Для подтверждения необходимо перейти по ссылке из лога сборки или на странице Signing Requests найти ваш запрос со статусом Waiting for approval, щелкнуть по его ID:

a3714d4019a55686b2a5f5403af552a5.png

a3714d4019a55686b2a5f5403af552a5.png

нажать кнопку Approve. Через несколько секунд статус изменится на Completed:

95cccded0f9edecbdce03c472d1c4b0f.png

95cccded0f9edecbdce03c472d1c4b0f.png

После этого процесс сборки продолжится и в логе отобразится следующая строка:

Signing request status is Completed

Дальше процесс завершается и полученные подписанные артефакты загружаются в релиз проекта. После скачивания видно, что все что было указано подписано доверенной цифровой подписью:

7739ecbc93b7af1a3323565ecfd1a185.png

7739ecbc93b7af1a3323565ecfd1a185.png

Запуск приложения теперь происходит более приятным образом, без предупреждений о неизвестном издателе.

Получившаяся конфигурация процесса сборки доступна в репозитории проекта: https://github.com/OpenNumismat/open-numismat/blob/master/.github/workflows/release.yml.

Заключительные штрихи

В требованиях для открытых проектов (https://signpath.org/terms) указано, что на сайте программы необходимо указывать Code signing policy со следующей информацией:

Free code signing provided by SignPath.io, certificate by SignPath Foundation

Что и было сделано.

При активации сертификата выпуска была опубликована ссылка на мой проект на сайте SignPath https://signpath.org/projects — здесь я в приятной компании?

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


ссылка на оригинал статьи https://habr.com/ru/articles/850052/