In genere, questo scenario viene risolto inviando comunque una richiesta di certificato e consentendo un messaggio di certificato vuoto (inviato dal client) quando il certificato non è necessario. Questo è ciò che fa mod_ssl
's SSLVerifyClient optional
(anche la differenza tra richiede e desidera l'autenticazione in Java ). Questo è il modo di stabilire i rapporti con i server per i quali non tutti i clienti potrebbero aver bisogno di presentare un certificato e chiaramente consentito all'interno di Specifica TLS (Sezione 7.4.6) :
This is the first message the client can send after receiving a server
hello done message. This message is only sent if the server requests
a certificate. If no suitable certificate is available, the client
SHOULD send a certificate message containing no certificates. That
is, the certificate_list structure has a length of zero. If client
authentication is required by the server for the handshake to
continue, it may respond with a fatal handshake failure alert.
Potresti essere in grado di dare un suggerimento usando l'estensione degli URL dei certificati client , anche se non penso che sia l'intento di questa estensione (che sarebbe un po 'un trucco). Non sono a conoscenza del fatto che questa estensione sia ampiamente supportata, il che causerebbe senz'altro problemi pratici se si desidera eseguirlo su un sistema di produzione.
Se in realtà non si desidera che al client venga richiesto un certificato, in alcuni casi, ciò che si può fare è utilizzare l'estensione SNI (Server Name Indication), che è sempre più supportata, offrendo così due distinti configurazioni del server in base al nome del server che il client sta richiedendo. Non ho provato, ma presumo che se si configurano due host virtuali distinti con Apache Httpd utilizzando SNI , e solo uno di loro è configurato per richiedere un certificato client, potresti riuscire a raggiungere il tuo obiettivo.
Il lato negativo è che avresti bisogno di impostare due nomi host per lo stesso server, ma non è un grosso problema come altre soluzioni che potrebbero richiedere un po 'di programmazione.
Ad esempio, anche se si presupponeva che l'indirizzo IP di origine fosse un discriminatore sufficiente tra i due casi d'uso, in Java, probabilmente dovresti implementare il server come ascoltando un ServerSocket
normale (non un SSLServerSocket
), controlla da quale indirizzo IP proviene, converti il socket accettato in SSLSocket
in modalità server e configuralo nello stage (prima che abbia luogo l'handshake) per richiedere un certificato client o meno, e solo dopo attiva il stretta di mano. (Non ho provato nulla di tutto ciò, ma sembrerebbe un modo ragionevole per gestire un caso del genere.) Questo sarebbe certamente più complesso della creazione di un SSLServerSocket
e dell'accettazione di SSLSocket
s preconfigurati direttamente. Immagino che altri stack SSL / TLS (in C o altri) non gestiscano questo caso in modo molto pulito.