Por lo general, este escenario se resuelve enviando una solicitud de certificado de todos modos y permitiendo un mensaje de certificado vacío (enviado por el cliente) cuando el certificado no es necesario. Esto es lo que mod_ssl
's SSLVerifyClient optional
hace (también la diferencia entre necesita y desea autenticación en Java ). Esta es la forma establecida de tratar con servidores para los cuales no todos los clientes deben presentar un certificado, y está claramente permitido dentro de Especificación TLS (Sección 7.4.6) :
Este es el primer mensaje que el cliente puede enviar después de recibir un servidor
hola mensaje hecho Este mensaje solo se envía si el servidor lo solicita.
un certificado. Si no hay un certificado adecuado disponible, el cliente
DEBE enviar un mensaje de certificado que no contenga certificados. Ese
Es decir, la estructura de lista de certificados tiene una longitud de cero. Si cliente
La autenticación es requerida por el servidor para que el handshake
Continuar, puede responder con una alerta de falla de saludo fatal.
Es posible que pueda dar una pista utilizando la extensión de URL de certificado de cliente , aunque no creo que esto sea así. la intención de esta extensión (eso sería un poco de un truco). No tengo conocimiento de que esta extensión sea ampliamente compatible, lo que sin duda causaría problemas prácticos si desea ejecutar esto en un sistema de producción.
Si realmente no desea que se le solicite un certificado al cliente en ciertos casos, lo que puede hacer es usar la extensión de Indicación de nombre de servidor (SNI), que es cada vez más compatible, por lo que ofrece dos Configuraciones del servidor dependiendo del nombre del servidor que el cliente está solicitando. No lo he intentado, pero supongo que si configura dos hosts virtuales distintos con Apache Httpd using SNI , y solo uno de ellos está configurado para solicitar un certificado de cliente, es posible que pueda lograr su objetivo.
La desventaja es que necesitaría configurar dos nombres de host para el mismo servidor, pero eso no es tan importante como otras soluciones que pueden requerir algo de programación.
Por ejemplo, incluso si asumió que la dirección IP de origen era un discriminador suficiente entre sus dos casos de uso, en Java, probablemente tendría que implementar el servidor escuchando un simple ServerSocket
(no un SSLServerSocket
), verifique de qué dirección IP proviene, convierta el socket aceptado en un SSLSocket
en modo servidor y configúrelo en la etapa (antes de que haya tenido lugar el protocolo de enlace) para solicitar un certificado de cliente o no, y solo entonces active el apretón de manos. (No he intentado nada de esto, pero esa sería una forma razonable de manejar ese caso). Esto ciertamente sería más complejo que crear un SSLServerSocket
y aceptar SSLSocket
s preconfigurado directamente. Me imagino que otras pilas de SSL / TLS (en C u otras) tampoco manejarán este caso de manera muy limpia.