OpenPGP переписывают на Rust: проект Sequoia
Секвойя Стагг в роще Олдер-Крик, Калифорния
В 2018 году три бывших разработчика GnuPG начали работу над проектом Sequoia — реализацией OpenPGP на Rust. Как известно, OpenPGP — это открытый стандарт шифрования данных, часто используемый для защищённой электронной почты;, а GnuPG — эталонная реализация этого стандарта.
Сами разработчики так изложили мотивацию за создание новой библиотеки OpenPGP:
- GnuPG трудно модифицировать. Код и API накапливались в течение 21 года. Модульные тесты отсутствуют. Компоненты тесно связаны друг с другом. Архитектура оставляет желать лучшего, и простой рефакторинг уже не поможет.
- Многие разработчики недовольны программными интерфейсами GnuPG. У инструмента командной строки GnuPG и соответствующих программных библиотек разная функциональность: некоторые команды доступны только из командной строки.
- Rust — безопасный для памяти язык, что автоматически исключает целый класс багов.
- GnuPG невозможно использовать под iOS из-за ограничений GPL.
Сейчас библиотека Sequoia под лицензией GPLv2 приближается к версии 1.0, хотя для этого предстоит решить ещё несколько проблем.
Новая библиотека должна быть лишена недостатков GnuPG. Хотя нужно заметить, что кроме «эталонной» реализации OpenPGP есть и другие, включая OpenKeychain, OpenPGP.js и RNP.
GnuPG подвергается критике в течение многих лет. Её критикуют за абсурдную сложность, универсальный дизайн типа «швейцарский нож»: GnuPG делает всё, но делает плохо, включая цифровую подпись, защиту паролем, шифрование открытым ключом, безопасную передачу файлов, подпись пакетов, защиту резервных копий, обмен сообщениями в чатах и т.д. Есть мнение, что в современную эпоху нужны специализированные инструменты: отдельная библиотека для безопасного обмена сообщениями, отдельная — для подписи пакетов, отдельная — для шифрования файлов (как утилита rage, написанная на Rust) и так далее. И необязательно все эти утилиты должны быть полностью совместимы со стандартом PGP.
Удостоилось критики стремление OpenPGP к обратной совместимости с шифрами 90-х годов, из-за чего настройки по умолчанию не соответствуют современным рекомендациям по надёжной криптографии и всегда возможно снижение безопасности через протоколы согласования. Проблема в том, что невозможно одновременно и сохранить обратную совместимость, и соответствовать современной надёжной криптографии.
Мы уже упоминали о мусорном коде: «Де-факто стандартной реализацией PGP является GnuPG. Эта программа не очень аккуратно написана. Там обширная кодовая база на C — языка с дублированием функциональности (например, в описании недавней атаки типа «отказ в обслуживании» на парсинг SKS сказано, что у него есть несколько парсеров ключей) с длинным послужным списком CVE, начиная от повреждения памяти до криптографической атаки по сторонним каналам. Иногда можно было удалить из сообщений аутентификацию, а GnuPG не замечал этого. Можно было скормить ему ключи без правильного отпечатка. В 2018 году уязвимость Efail была вызвана тем, что GnuPG по запросу отдавал неаутентифицированный открытый текст», — пишет Latacora.
Ещё одна проблема — (не)удобство использования.
Несколько лет назад было проведено исследование юзабилити PGP, в ходе которого группу технических специалистов поместили в комнату с компьютером и попросили настроить PGP. Через два часа никто из них ещё не вышел. — Тед Унангст, разработчик OpenBSD и LibreSSL
Другие претензии — небезопасность долговременного хранения одного и того же ключа, совершенно слабая система аутентификации зашифрованного текста MDC, отсутствие прямой секретности и топорные гигантские ключи.
Sequoia представляет собой современный инструментарий OpenPGP, который решает многие из перечисленных проблем, пишет LWN. Sequoia уже принята на вооружение несколькими другими проектами, в том числе keys.openpgp.org, OpenPGP CA, koverto, Pijul и KIPA.
Проект финансируется фондами p≡p (pep) и Wau Holland, при этом все разработки ведутся в открытом режиме.
Новая библиотека ориентирована на безопасность и корректность, используя при этом самую надёжную современную криптографию. Разработчики обещают мощный инструментарий, включая программу командной строки и подкоманды в стиле Git.
$ echo hi | sq encrypt --recipient neal
-----BEGIN PGP MESSAGE-----
wcBMA8K4GQVsZSWYAQgAllrQ+9490eoFdB/jLrVvGl+IVtGJWPFDg9uhcl0D8k05
AWz8ZU2sd6GzoCH1nRpwASJWHxloNbPgvxhNRRVReg3GgfFwMkcoNJ2Xb4zocvx+
niH7ZlP9Py6kseuqtjhQZEyvtIfWc58TK9DRdPp5suzS3Y9Zbew9vC2N2u+8YsKL
BbbminTZqLYbt/00ZT/ZuDbtHhoDUxlnCK2Y2R6NZvuvwS1ujI0EOfdOagZO0z5k
hs8U9Xgk1/BWpQtKn3ygMDO0401nBBbwNgialcu/8yFS+wXoifRaj60Cbxhjv2/G
aTcl9loYpN93BL0a7EbKmcwDl14HwosKdkMj4Px25dI0AZjLxI7TBX18e+hBu5vr
q83G7aEwllpiDU3z+rFXBjsWDOwP2UBf05D/Bl05eSYx4x7UnQ==
=qAvC
-----END PGP MESSAGE-----
Реализован ясный интерфейс для парсера и инспекции пакетов, а также hex-дампы, которые можно сейчас посмотреть в онлайн-демо.
$ sq packet dump --hex message.pgp
New CTB, 13 bytes: One-Pass Signature Packet
Version: 3
Type: Binary
Pk algo: EdDSA Edwards-curve Digital Signature Algorithm
Hash algo: SHA512
Issuer: 83F8 2E4F E9A5 E098
Last: true
00000000 c4 0d frame
00000002 03 version
00000003 00 sigtype
00000004 0a hash_algo
00000005 16 pk_algo
00000006 83 f8 2e 4f e9 a5 e0 98 issuer
0000000e 01 last
В отличие от GnuPG, где инструмент командной строки gpg более мощный, чем библиотека, Sequoia — это прежде всего библиотека; вся её функциональность доступна через открытые API. Проект планирует предоставить два «уровня» API: низкоуровневую реализацию спецификаций OpenPGP и высокоуровневый API с разумными значениями по умолчанию, чтобы облегчить пользователям типичные задачи, такие как подпись пакетов и проверка подписи:
$ sqv --trace --keyring tails-signing.key \
tails-amd64-3.11.iso.sig tails-amd64-3.11.iso
Will check signature allegedly issued by A8B0 F4E4 5B1B 50E2.
Found key A8B0 F4E4 5B1B 50E2.
Checking signature allegedly issued by A8B0 F4E4 5B1B 50E2.
Signature by A8B0 F4E4 5B1B 50E2 is good.
A490 D0F4 D311 A415 3E2B B7CA DBB8 02B2 58AC D84F
1 of 1 signatures are valid (threshold is: 1).
$ echo "Just check the exit status: $?"
Just check the exit status: 0
Несмотря на низкоуровневую реализацию спецификаций OpenPGP, разработчики исключили некоторые устаревшие и опасные стандарты, таких как хэши MD5.
Ещё перед стартом инициативы основатели проекта встретились с видными членами сообщества OpenPGP и конечными пользователями, чтобы обсудить планы проекта и убедиться, что их подход действительно обоснован. Сейчас идёт активная разработка. Судя по записям в репозитории и трекере, там примерно 30 участников, а с момента объявления в апреле 2020 года о подготовке версии 1.0 сделано три релиза. Последний релиз 0.19.0 вышел в августе 2020 года — в нём самым заметным улучшением является интеграция в качестве бэкенда Windows Cryptography API: Next Generation (CNG) вместо Nettle, у которого есть проблемы в средах, отличных от POSIX.
Для дополнительной безопасности Sequoia планирует использовать разделение процессов между службами, обрабатывающими открытые и закрытые ключи (как в gpg-agent). Здесь для межпроцессной связи внедряется протокол сериализации Cap’n Proto — это что-то похожее на Protocol Buffers, только быстрее.
В презентации разработчики отмечают, что разделение процессов не всегда возможно, например, в средах iOS. Когда оно недоступно, Sequoia планирует использовать общую базу данных SQLite для связи между службами в процессе, как своеобразный «колокейшн».
Sequoia использует концептуально иной подход к связкам открытых ключей: они спроектированы так, чтобы быть «больше похожими на адресную книгу, чем на связку ключей PGP». Ключи хранятся по идентификаторам пользователей (petname), с возможностью привязки произвольных структурированных данных, полезных при реализации моделей доверия. Разработчики говорят, что такой подход больше соответствует тому, как пользователи на самом деле представляют ключи: они связаны с именами, а не с набором абстрактных идентификаторов. Это одна из областей, где Sequoia отличается от других реализаций OpenPGP.
Кроме того, всем ключам присваивается «реалм», указывающий целевое назначение ключа. Сейчас поддерживаются два реалма: «Контакты» и «Ключ обновления программного обеспечения».
Связка ключей автоматически обновляется с удалённых серверов (аналогично parcimonie), чтобы своевременно отслеживать изменения, новые субключи и отзывы ключей. Документация указывает, что это можно делать с помощью анонимизированных сервисов, таких как Tor, в дополнение к более распространённым методам шифрования TLS.
Реализация приватной связки ключей в Sequoia будет поддерживать свойство прямой секретности через спецификации OpenPGP, которые не реализованы во многих других библиотеках. Эти спецификации позволяют разграничить данные «в покое» (зашифрованное хранилище) и данные «в движении» (зашифрованная передача). С точки зрения безопасности хорошо периодически менять ключи для данных «в движении», но сохраняя возможность расшифровывать данные «в покое». В презентации одного из разработчиков Джастуса Винтера сравниваются функции прямой секретности Sequoia с другими реализациями OpenPGP.
Sequoia пользуется всеми преимуществами безопасности памяти, которые даёт язык Rust.
Что такое безопасность памяти, популярно объясняется в статье Майкла Хикса. Если простыми словами, то имеется в виду, что ни в каком состоянии программа не может получить доступ к недействительной памяти. Речь идёт о следующих ошибках:
- переполнение буфера;
- разыменование нулевого указателя;
- сохранение указателя после освобождения памяти (use-after-free);
- использование неинициализированной памяти;
- попытка программы дважды освободить одну и ту же ячейку (double-free).
Нарушения безопасности памяти приводят к уязвимостям, таким как утечка данных и удалённое выполнение кода. Хотя некоторые языки смирились с падением производительности ради безопасности памяти, концепция владения в Rust обеспечивает безопасность и минимизирует накладные расходы.
Судя по текущей разработке Sequoia, предпринимаются значительные усилия по написанию модульных тестов для предотвращения регрессий и повышения качества кода.
Sequoia ориентирована на «современные платформы», включая Linux, Windows, macOS, Android и iOS с максимальным использованием существующих криптографических инструментов; целью проекта является тесная интеграция с криптографическими сервисами конкретной платформы. Например, на устройствах iOS планируется использовать сопроцессор Secure Enclave, когда он доступен. Sequoia также предоставляет интерфейс внешних функций (FFI) для интеграции проекта с программами, написанными на других языках. В настоящее время предлагаются биндинги (связки) с Python и C. Однако следует отметить, что программы с этими биндингами лишены встроенной безопасности памяти Rust, поэтому для правильной работы с памятью использования опубликованы специальные правила.
Компоненты Sequoia
Выпуск версии 1.0 может состояться в ближайшее время, хотя сначала выйдет только низкоуровневый API, то есть крейт sequoia-openpgp и его зависимости. Это значит, что Sequoia пока не станет заменой инструментов вроде GnuPG для всех пользователей: первый крупный релиз будет сосредоточен на библиотеке для разработчиков. Разработчикам Sequoia нужно закончить инструмент командной строки sq
, который не войдёт в версию 1.0. Кроме того, всё ещё в стадии разработки службы хранения ключей — вместе с инструментом командной строки это один из главных приоритетов проекта после выхода версии 1.0.
В целом, приятно видеть проект, который пытается облегчить использование технологии OpenPGP и сделать её более доступной. Видно, что за три года разработчикам удалось добиться значительного прогресса. Документация позволяет использовать эту библиотеку в приложениях. Тем не менее, Sequoia предстоит пройти ещё немалый путь, прежде чем она станет надёжным криптографическим инструментом. Самое главное, что код нуждается в аудите. На странице проекта говорится, что он ещё не прошёл аудит, но «как только мы выпустим основной крейт Sequoia, он будет проверен третьей стороной». Дата выпуска версии 1.0 не объявлена, но похоже, что это состоится в ближайшее время.
На правах рекламы
VDS для программистов с новейшим железом, защитой от атак и огромным выбором операционных систем. Максимальная конфигурация — 128 ядер CPU, 512 ГБ RAM, 4000 ГБ NVMe.