Как вы обнаружили, вы можете отключить проверку сертификата на уровне рукопожатия SSL / TLS в Apache Httpd с помощью SSLVerifyCLient optional_no_ca
.
Вторая проблема, с которой вы столкнетесь, - заставить клиента отправить сертификат. Поскольку ваш сертификат не предназначен для использования в рамках PKI, он может быть самоподписанным и иметь разных эмитентов.
При запросе сертификата клиента сервер отправляет клиенту CertificateRequest
сообщение TLS во время передачи запроса. Это сообщение содержит certificate_authorities
список:
Список отличительных названий допустимых центров сертификации. Эти отличительные имена могут указывать желаемое отличительное имя для корневого ЦС или для подчиненного ЦС; таким образом, это сообщение может использоваться для описания как известных корней, так и желаемого пространства авторизации. Если список certificate_authorities пуст, то клиент МОЖЕТ отправить любой сертификат соответствующего ClientCertificateType, если только нет внешнего соглашения об обратном.
Браузеры используют это для выбора клиентского сертификата для отправки (если есть).
(Обратите внимание, что часть о пустом списке есть только в спецификации, начиная с TLS 1.1 и далее. В SSL 3.0 и TLS 1.0 об этом ничего не говорится, и на практике это также будет работать.)
Вы получаете два варианта для этого.
Если клиентские сертификаты, которые вы ожидаете, будут самозаверяющими, все они будут иметь разных эмитентов. Поскольку вы не будете знать, чего ожидать, серверу нужно будет отправить пустой список. Чтобы сделать это, используйте SSLCADNRequestFile
директиву и укажите ее в файле, который содержит только пустую строку (если я хорошо помню, он не работает с полностью пустым файлом).
Второй (менее чистый) вариант. Согласовать DN эмитента, общий для всех ожидаемых клиентских сертификатов, независимо от того, были ли они действительно выданы этим сертификатом CA (или даже существует этот CA). Поступая так, вы бы значительно нарушили модель PKI (подробнее).
Если вы согласны с DN эмитента, например CN=Dummy CA
(например). Любой может создать самозаверяющий сертификат, используя в CN=Dummy CA
качестве DN субъекта (и DN эмитента), возможно, с разными ключами. Хотя в SSLCADNRequestFile
директиве предполагается, что для создания списка будут настроены сертификаты, они вообще не используются для проверки сертификата клиента, это просто сложный (но естественный в контексте других директив) способ настройки certificate_authorities
списка. Если вы, как служба, поместите самоподписанный сертификат с этими именами SSLCADNRequestFile
, это приведет к CertificateRequest
использованию сообщения TLS CN=Dummy CA
в certificate_authorities
списке (на данном этапе это просто имена, а не сертификаты). После этого клиент сможет получить свой собственный сертификат с DN эмитента.CN=Dummy CA
независимо от того, может ли его подпись быть проверена этим сертификатом (теми же ключами) или нет, так как в любом случае проверка подписи не вовлечена в эти шаги.
При этом, помните, что с SSLVerifyCLient optional_no_ca
, никакая реальная проверка сертификата не сделана (я полагаю, что вы могли бы проверить SSL_CLIENT_VERIFY
переменную, если ваша ручная проверка является просто резервным решением для PKI, который вы все равно настроили). Все, что вы будете знать на этом этапе, - это то, что у клиента есть закрытый ключ для сертификата открытого ключа, который он представил (гарантировано CertificateVerify
сообщением TLS ): вам потребуется выполнить некоторую форму проверки, если вы хотите, чтобы какая-то аутентификация была Сортировать. (Вы не можете доверять какому-либо содержимому сертификата, то есть любой привязке между его открытым ключом и именами / атрибутами, которые он содержит.)
Это не будет работать для файлов, но вы можете сделать это для приложения (например, PHP / CGI / ... даже Java, если вы передаете сертификат на прокси-сервер Java). Одним из основных способов было бы иметь заранее известный список открытых ключей, или вы можете посмотреть на идеи в FOAF + SSL / WebID .