Кратко

  • RFC 6487 запрещает поля authorityCertIssuer и authorityCertSerialNumber в Authority Key Identifier ресурсного сертификата RPKI, хотя общий профиль X.509 в RFC 5280 определяет оба поля как необязательные.
  • Коммит Barry 994a598 связал authorityCertIssuer с парсером GeneralNames, которому нужен массив. На следующий день коммит Rapport b1a59a заменил прежнюю одиночную строку массивом с одним rfc822Name и исправил ожидаемое сообщение FORT.
  • Сценарий запускает Barry, затем выбранную relying party, проверяет журнал и только после этого сравнивает VRP с пустым набором. Код задаёт порядок, но в открытых материалах нет протокола выполнения и декодированного сертификата.
  • Rapport перечисляет четыре валидатора, однако точная проверка причины в этом сценарии срабатывает лишь для fort2. Для остальных пустой вывод показывает последствие, не обязательно устанавливая причину.

Отрицательный тест обязан предъявить положительный факт

Профильная норма сформулирована чётко. Расширение Authority Key Identifier связывает сертификат с открытым ключом издателя. RFC 6487 требует его во всех ресурсных сертификатах, кроме особого случая самоподписанного сертификата, объявляет некритическим и запрещает authorityCertIssuer вместе с authorityCertSerialNumber. В более общем RFC 5280 оба компонента допустимы как необязательные, но должны присутствовать парой. RPKI сознательно сужает возможности базового X.509.

Негативный сценарий выглядит просто: создать сертификат CA с запрещённым компонентом, поместить под ним ROA и убедиться, что валидатор не экспортирует соответствующую маршрутную нагрузку. Но первое действие нельзя считать выполненным по умолчанию. Генератор может не распознать описание, пропустить поле или завершиться до записи сертификата. Во всех случаях VRP окажется ноль, хотя валидатор ни разу не увидит намеченное нарушение.

Barry выполняет именно роль производителя входа. В 2025 году LACNIC представила его как инструмент, создающий корректные и намеренно некорректные репозитории RPKI из файлов «ключ—значение». Rapport подаёт эти репозитории relying party и исследует её выход. Такая архитектура делает сложные граничные случаи повторяемыми, но превращает генератор в первый элемент доказательства.

Почему строка не равна GeneralNames

1 сентября 2026 года коммит Barry 994a598321336baf1767f0fbfb460ed96c29fe4f добавил поддержку authorityCertIssuer. В ext.c поле связано с внутренним типом ft_gnames. Функция parse_gnames в field.c принимает множество или массив, считает элементы, выделяет ASN.1-объект GeneralName для каждого и разбирает элементы как объекты. Значение другого типа отправляется в ветку ошибки, где явно требуется массив в квадратных скобках.

Добавленный тем же коммитом функциональный fixture Barry показывает формат на трёх элементах: rfc822Name, IP-адрес и registeredID. Это не образец соответствующего профилю RPKI сертификата, а проверка того, какие варианты GeneralName способен кодировать генератор.

Предыдущая версия сценария Rapport использовала authorityCertIssuer = "CN=Fake Issuer": одиночную строку, а не массив. Сопоставление файлов позволяет сделать ограниченный вывод — эта форма не соответствует нынешнему контракту parse_gnames. Нельзя утверждать, что конкретный исторический запуск завершился именно этой ошибкой или что старая версия Barry вела себя так же. Открытого журнала запуска и отпечатка бинарного файла нет.

2 сентября Rapport исправил fixture в коммите b1a59a39ea3b3f8ddc66571a7177c8afb1d0967c. Значение стало массивом из одного объекта: type = rfc822Name, а в value записана примерная строка почтового адреса. Правдоподобие адреса издателя здесь несущественно: RPKI запрещает сам компонент. Важна совместимость формы с типовой системой Barry, позволяющая построить запрещённое состояние.

Ожидаемый журнал указывал не на то поле

До исправления run.sh искал в журнале FORT сообщение о authorityCertSerialNumber, хотя fixture пытался добавить authorityCertIssuer. После b1a59a assertion называет issuer. Исправлена вторая связь: даже при верно созданном объекте тест вводил бы в заблуждение, приписывая отказ другому дефекту.

Порядок нового сценария полезен сам по себе: run_barry, затем run_rp, после этого check_logfile и в конце check_vrps. При аудируемом выполнении каждый переход должен оставлять отдельный след. Нужны версия и хеш Barry, хеш fixture, код завершения, сгенерированный сертификат и декодированный AKI; далее продукт, версия, конфигурация и TAL валидатора; сигнал отказа; хеши ожидаемого и фактического наборов VRP.

В зафиксированных публичных данных такого комплекта нет. GitHub показывает ноль check runs для b1a59a; у Rapport также не обнаружены теги и релизы. Это не доказывает отсутствия локальных или закрытых тестов. Оно задаёт границу публичного утверждения: исправление исходника нельзя без дополнительного артефакта выдавать за выполненный, воспроизводимый и привязанный к версии результат.

Пустота — следствие, а не диагноз

Функция check_vrps формирует ожидаемый файл из аргументов. В данном случае аргументов нет, поэтому ожидание пусто. CSV-вывод relying party приводится к общей форме, сортируется и сравнивается с пустым файлом. Успешное сравнение устанавливает, что из этого пути не вышло ни одного VRP.

Проверка необходима: под дефектным сертификатом CA находится ROA, и он не должен превращаться в принятую авторизацию происхождения. Однако к пустому набору ведут разные причины. Валидатор мог верно отвергнуть AKI, репозиторий мог не загрузиться, цепочка могла содержать другой дефект, TAL мог быть выбран неверно, а Barry мог остановиться до публикации объекта. Без доказательства конструкции и телеметрии запуска пустой вывод не различает эти сценарии.

Для FORT есть дополнительный сигнал. Сценарий вызывает check_logfile fort2, а helper проверяет файл лишь тогда, когда активная переменная RP совпадает с первым аргументом. Иначе он возвращается без поиска. Поэтому точное сообщение с authorityCertIssuer — assertion, специфичный для FORT 2.

README закреплённой версии перечисляет fort2, routinator, rpki-client и rpki-prover; за один запуск выбирается один продукт. Наличие четырёх адаптеров не создаёт четырёх равноценных диагностик. Для остальных трёх видимый общий контроль — пустой VRP. Он подтверждает узкое «нагрузка не экспортирована», но не обязательно «отказ вызван данным полем».

Три колонки вместо одного зелёного значка

Полезная оператору матрица соответствия должна разделить конструкцию, решение и выход. В первой колонке — версия и бинарный отпечаток Barry, fixture, статус завершения, сертификат и разбор AKI. Во второй — версия и конфигурация валидатора, TAL, код либо сообщение отказа. В третьей — ожидаемые и наблюдаемые VRP. Цвет может суммировать эти данные, но не заменять их.

Не каждый валидатор обещает стабильный текст человекочитаемого журнала. Переносимый набор тестов не обязан навязывать одну фразу. Допустимы структурированная категория, собственный код продукта или строго ограниченное утверждение «ни одна нагрузка не принята». Сопоставимость достигается точностью смысла каждой ячейки, а не искусственным единообразием интерфейсов.

Следует также различать три степени зрелости: тест присутствует в исходнике, тест выполнен на идентифицированной сборке, результат опубликован в версионированном наборе. Первая даёт возможность рецензирования, вторая — воспроизведения, третья — связи с устанавливаемым ПО. Сведение их к слову «пройден» превращает меняющуюся ветку в неподвижную гарантию.

Декодированный сертификат соединяет намерение с входом

Самое компактное дополнение, способное снять большую часть неопределённости, — сохранить сертификат, созданный Barry, и независимо разобрать его AKI. Fixture показывает намерение автора теста, а parser — форму данных, которую умеет принимать программа. Только DER-артефакт показывает байты, фактически подготовленные для валидатора. Хеш сертификата, версия средства декодирования и перечень видимых полей свяжут замысел с конкретным входом.

Такой артефакт также разделяет новую возможность Barry и её применение в определённом запуске Rapport. 994a598 добавляет привязку поля, обработчик GeneralNames и функциональную проверку; массив из b1a59a соответствует этому контракту. Но без результата запуска неизвестно, какой бинарный файл выбрал runner, не изменила ли конфигурация путь и именно ли этот сертификат оказался в опубликованном тестовом репозитории. Связность исходника необходима, но она не заменяет идентичность исполнения.

Протокол не обязан быть громоздким. Достаточно небольшого машиночитаемого манифеста: хеш описания, коммит и хеш бинарного Barry, список созданных объектов, версия валидатора, время начала и окончания, коды выхода, категория диагностики, хеши ожидаемых и фактических VRP. Если связать его с задачей CI или релизом, он сохранит проверяемость лучше снимка веб-журнала.

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

Такой формат не заставляет четыре продукта говорить одним языком. Каждый может сохранить собственные коды и сообщения, а матрица будет сравнивать общие контрольные точки: был ли объект получен, закончился ли цикл, принята ли нагрузка и насколько узок подтверждённый вывод. Отличия интерфейсов тогда становятся наблюдаемыми данными, а не поводом заполнить пробел одинаковой зелёной меткой.

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

То же относится к настройкам валидатора. Режим загрузки, кэш, выбранный TAL и параметры строгой проверки должны входить в идентификатор опыта: одинаковая версия с другой конфигурацией может пройти по иному пути.

Для эксплуатации это даёт естественное разделение решений. Тест в исходнике отвечает за заявленный охват. Исполнение на кандидатной сборке поддерживает решение об обновлении. Результат в релизе поддерживает последующий аудит. Ни один из этих документов не должен молча подменять два остальных.

В декабре 2025 года LACNIC называла Barry и Rapport ранними проектами и описывала прежде всего FORT. Более поздний README называет уже четыре селектора. Эти материалы фиксируют развитие во времени. Старый текст не отменяет нынешние возможности, а нынешний список не создаёт задним числом четыре симметричных результата.

Самый сильный допустимый вывод потому намеренно скромен. Barry получил механизм кодирования authorityCertIssuer; Rapport подогнал fixture под этот тип и исправил диагностику FORT. Определение теста стало последовательнее. Открытые свидетельства не удостоверяют успешный запуск ни на FORT, ни на трёх других relying parties.

Источники

  1. LACNIC Blog, “Open-Source Projects at LACNIC”: https://blog.lacnic.net/en/open-source-projects-lacnic/
  2. Коммит Barry 994a598: https://github.com/LACNIC/barry/commit/994a598321336baf1767f0fbfb460ed96c29fe4f
  3. Парсер и привязка поля Barry: https://github.com/LACNIC/barry/blob/994a598321336baf1767f0fbfb460ed96c29fe4f/src/field.c и https://github.com/LACNIC/barry/blob/994a598321336baf1767f0fbfb460ed96c29fe4f/src/ext.c
  4. Функциональный fixture GeneralNames: https://github.com/LACNIC/barry/blob/994a598321336baf1767f0fbfb460ed96c29fe4f/test/functional/tests/gnames.rd
  5. Исправление Rapport b1a59a: https://github.com/LACNIC/rapport/commit/b1a59a39ea3b3f8ddc66571a7177c8afb1d0967c
  6. Исправленные fixture и runner: https://github.com/LACNIC/rapport/blob/b1a59a39ea3b3f8ddc66571a7177c8afb1d0967c/tests/rfc6487/4.8.3-c-aki-with-authoritycertIssuer-rejected/rd и https://github.com/LACNIC/rapport/blob/b1a59a39ea3b3f8ddc66571a7177c8afb1d0967c/tests/rfc6487/4.8.3-c-aki-with-authoritycertIssuer-rejected/run.sh
  7. Helpers и README Rapport: https://github.com/LACNIC/rapport/blob/b1a59a39ea3b3f8ddc66571a7177c8afb1d0967c/tools/checks.sh и https://github.com/LACNIC/rapport/blob/b1a59a39ea3b3f8ddc66571a7177c8afb1d0967c/README.md
  8. RFC 6487: https://www.rfc-editor.org/rfc/rfc6487.html
  9. RFC 5280: https://www.rfc-editor.org/rfc/rfc5280.html
  10. Fixture и runner до исправления в коммите 69da5fe: https://github.com/LACNIC/rapport/blob/69da5fe98cf09594fc009f4151a84368c08489ba/tests/rfc6487/4.8.3-c-aki-with-authoritycertIssuer-rejected/rd и https://github.com/LACNIC/rapport/blob/69da5fe98cf09594fc009f4151a84368c08489ba/tests/rfc6487/4.8.3-c-aki-with-authoritycertIssuer-rejected/run.sh
  11. Файлы, измененные исправляющим коммитом b1a59a: https://github.com/LACNIC/rapport/commit/b1a59a39ea3b3f8ddc66571a7177c8afb1d0967c/checks
  12. История пути fixture в main: https://github.com/LACNIC/rapport/commits/main/tests/rfc6487/4.8.3-c-aki-with-authoritycertIssuer-rejected/rd
  13. Теги и релизы Rapport: https://github.com/LACNIC/rapport/tags и https://github.com/LACNIC/rapport/releases