Кратко

  • Расширение TLS 1.3 certificate_authorities передаёт упорядоченные Distinguished Name в DER. Они помогают другой стороне выбрать сертификат, но не передают сертификат УЦ, доверенный ключ, проверенный путь или прикладное разрешение.
  • В ClientHello список влияет на выбор серверной цепочки, а в CertificateRequest — на выбор клиентской. Одинаковый формат не объединяет эти два решения и их владельцев.
  • Надёжный журнал разделяет генерацию списка, оценку кандидатов, проверку пути и сопоставление аутентифицированной личности с разрешённым действием.

Успешная проверка, после которой последовал отказ

Представим клиент с несколькими сертификатами. Библиотека находит имя УЦ из CertificateRequest, выбирает подходящую учётную запись, доказывает владение закрытым ключом. Сервер строит путь к якорю из своей действующей конфигурации и принимает его.

Но SAN может относиться к другому пространству имён, субъект может отсутствовать в реестре арендатора, а роль — не включать запрошенное действие. Проверка пути отвечает за происхождение и ограничения сертификата. Она не решает, можно ли этой личности получить секрет, изменить маршрут или подписать артефакт.

Поле ca_allowed=true не сокращает вывод, а смешивает четыре разных вывода. По нему нельзя узнать, было ли имя лишь передано, был ли сертификат выбран, какой ключ стал якорем и дала ли прикладная политика доступ.

Имя не является объектом доверия

IANA закрепляет за certificate_authorities значение расширения 47. RFC 9846 задаёт непустой вектор DER-кодированных X.501 Distinguished Name. Имя может обозначать желаемый якорь или подчинённый УЦ и должно направлять выбор сертификата.

В расширении нет открытого ключа УЦ, его ограничений, политики или записи trust store. Два сертификата УЦ могут иметь одинаковый subject и разные ключи. Subject можно извлечь и из сертификата, который не имеет полномочий УЦ. Совпадение DN поэтому не устанавливает, какому ключу доверяет отправитель.

Проверка пути по RFC 5280 использует реальный якорь и оценивает подписи, сроки, Basic Constraints, Name Constraints, Key Usage и входные параметры политики. Якорь может не передаваться в цепочке, поскольку распространяется независимо. Имя из списка не заменяет ни одну из этих проверок.

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

Один тип расширения, два направления данных

Список в ClientHello помогает серверу выбрать свой сертификат и альтернативную цепочку. Список в CertificateRequest помогает клиенту выбрать сертификат для аутентификации. В первом случае список создаёт клиент, во втором — сервер.

OpenSSL отдельно предупреждает: имена УЦ, отправляемые клиентом, видны серверу в открытом виде. Автоматическая выгрузка корпоративного хранилища способна раскрыть внутренние названия и структуру PKI. Слишком длинный серверный список, в свою очередь, увеличивает размер и работу рукопожатия.

Старое расширение trusted_ca_keys в TLS 1.3 не используется. Многоверсионный ClientHello может нести старые сигналы, поэтому телеметрия должна связывать согласованную версию, сообщение, направление и номер расширения.

Выбор происходит на пересечении ограничений

Имя УЦ — только один фильтр. На результат влияют signature_algorithms, иногда signature_algorithms_cert, тип и наличие закрытого ключа, алгоритм подписи сертификата, Key Usage, EKU, SNI, OID-фильтры, срок действия и цепочки, которые реализация действительно умеет собрать.

Отвергнутые кандидаты необходимы для объяснения. Имя может совпасть, а EKU — нет; алгоритм может подходить, но закрытого ключа нет; сертификат может быть действительным, но его цепочка не достигает указанного имени. Один отпечаток выбранного leaf этого не показывает.

Если подходящего клиентского сертификата нет, TLS 1.3 предусматривает пустое сообщение Certificate. Сервер может продолжить по своему профилю либо выдать certificate_required. Пустота — точный результат, а не повод незаметно подставлять постороннюю личность.

Объявляемый список и хранилище проверки живут отдельно

OpenSSL разделяет API имён, отправляемых другой стороне, и API доверенных сертификатов. Настройка списка не добавляет доверия. Пути проверки загружаются отдельно.

Это позволяет поставить показательный отрицательный тест: объявить subject УЦ, но не доверять соответствующему ключу. Клиент может выбрать совпадающую цепочку, а сервер — корректно ответить unknown_ca. Возможна и обратная ситуация: локально доверенная цепочка не представлена в подсказке.

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

Загрузчик клиентских имён УЦ OpenSSL извлекает subject и не ограничивает вход только сертификатами УЦ. Успешно прочитанный файл доказывает разбор, но не полномочия каждой записи.

Аутентификация ещё не создаёт роль

После проверки пути правила протокола интерпретируют SAN и другие признаки личности. Приложение затем связывает нормализованный субъект с арендатором, учётной записью, workload, ролью и действием. Для этого могут потребоваться точная форма SAN, пара issuer–subject, policy OID, действующая регистрация или внешнее право.

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

OpenSSL, GnuTLS и BoringSSL предоставляют раздельные callbacks выбора и функции проверки. Установленный callback показывает возможность, но только вызов с идентификатором соединения доказывает исполнение. Некоторые представления списка в BoringSSL действительны лишь в пределах callback, поэтому DER следует копировать или хешировать там же.

При PSK-resumption главный обмен TLS 1.3 может не содержать новой CertificateRequest. Если сертификаты не передавались, нельзя регистрировать новую оценку списка или клиентской личности.

Отрицательные проверки сохраняют границы

Объявите DN без доверенного ключа. Создайте два УЦ с одинаковым subject и доверьте только одному. Предложите совпадающий по имени сертификат с неверным EKU, сроком, политикой либо отсутствующим закрытым ключом. Сохраните точную причину исключения каждого кандидата.

Добейтесь успешного пути и затем запретите субъект на границе арендатора. Удалите все подходящие credentials и наблюдайте пустой Certificate и последующее решение сервера. Меняйте список и store по отдельности, проверяя сигнал о расходящихся поколениях.

Перехватите ClientHello и измерьте раскрытие, испытайте большие векторы DN, возобновите сессию без прироста счётчика новой аутентификации. Различайте configured, invoked, selected, verified и authorized.

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

Источники