Як ви виявили, ви можете відключити перевірку сертифікатів на рівні рукостискання SSL / TLS в межах Apache Httpd, використовуючи SSLVerifyCLient optional_no_ca.
Друга проблема, з якою ви збираєтеся зіткнутися з тим, що ви намагаєтеся зробити, - це змусити клієнта надіслати сертифікат. Оскільки ваш сертифікат не повинен бути в межах PKI, він може підписатись і мати різних емітентів.
Під час запиту клієнтського сертифіката сервер надсилає клієнту CertificateRequestTLS-повідомлення під час ручної передачі. Це повідомлення містить certificate_authoritiesсписок:
Список відомих імен прийнятних сертифікаційних органів. Ці розрізнені імена можуть визначати бажане відмінне ім’я для кореневого ЦЗ або для підлеглого ЦА; таким чином, це повідомлення може бути використане для опису як відомих коренів, так і потрібного простору авторизації. Якщо список сертифікатів_авторитетів порожній, клієнт МОЖЕ надсилати будь-який сертифікат відповідного ClientCertificateType, якщо немає зовнішньої домовленості, яка суперечить.
Браузери використовують це, щоб вибрати, який сертифікат клієнта надсилати (якщо такий є).
(Зверніть увагу, що частина про порожній список міститься лише в специфікації від TLS 1.1. SSL 3.0 і TLS 1.0 про це мовчать, і на практиці це також буде працювати.)
Ви отримуєте два варіанти для цього.
Якщо клієнтські сертифікати, які ви очікуєте, підписуватимуться самостійно, всі вони матимуть різних емітентів. Оскільки ви не знаєте, що очікувати, серверу потрібно буде надіслати порожній список. Для цього скористайтеся SSLCADNRequestFileдирективою та вкажіть її на файл, який містить лише порожній рядок (якщо я добре пам’ятаю, він не працює з повністю порожнім файлом).
Другий (менш чистий) варіант. Погодьтесь щодо DN-емітента, спільного для всіх клієнтських сертифікатів, яких ви очікуєте, незалежно від того, чи вони були видані цим сертифікатом CA (чи є, чи існує ЦА чи ні). Роблячи це, ви б значно порушили модель PKI (більше).
Якщо ви погоджуєтесь з DN-емітентом, наприклад CN=Dummy CA(наприклад). Будь-який бажаючий може створити сертифікат, який підписує власний підпис, використовуючи CN=Dummy CAяк суб’єкт DN (і видавець DN), можливо, за допомогою різних ключів. Хоча SSLCADNRequestFileдиректива очікує, що вона буде налаштована сертифікатами для складання списку, вони взагалі не використовуються для перевірки клієнтського сертифіката, це просто складний (але природний у контексті інших директив) спосіб налаштування certificate_authoritiesсписку. Якщо ви, як сервіс, вкладете сертифікат cert з такими іменами SSLCADNRequestFile, який підписується , це зробить CertificateRequestповідомлення TLS CN=Dummy CAу certificate_authoritiesсписку (це лише імена, а не церти на цьому етапі). Потім клієнт зможе отримати власний сертифікат у видачі DNCN=Dummy CA, незалежно від того, чи може його підпис підтверджений цим сертифікатом (тими самими ключами) чи ні, оскільки жодна перевірка підпису в цих кроках жодного разу не бере участь.
З цього SSLVerifyCLient optional_no_caприводу пам’ятайте, що при цьому не проводиться справжня перевірка сертифікатів (я думаю, ви могли перевірити SSL_CLIENT_VERIFYзмінну, якщо ваша ручна перевірка є лише резервним рішенням для PKI, який ви все одно налаштували). Все, що ви знаєте на цьому етапі, - це те, що клієнт має приватний ключ для представленого ним сертифіката відкритого ключа (гарантованого CertificateVerifyповідомленням TLS ): вам потрібно буде виконати певну форму перевірки, якщо ви хочете, щоб там була автентифікація деяких сортувати. (Ви не можете довіряти жодному змісту сертифіката, тобто будь-якій прив'язки між його відкритим ключем та іменами / атрибутами, які він містить.)
Це не буде добре для файлів, але ви можете зробити це для програми (наприклад, PHP / CGI / ... навіть Java, якщо ви передасте сертифікат на проксі-сервер Java). Одним із основних способів було б мати заздалегідь відомий список відкритих ключів, або ви можете подивитися на ідеї у FOAF + SSL / WebID .