Determina se un server richiede un certificato client usando openssl s_client

6

Sto utilizzando openssl per connettermi ai server per rilevare se richiedono un certificato client.

Attualmente sto usando questo comando:

openssl s_client -connect pokyloky.com:5222 -state 2>&1 | grep 'server certificate request' 

SSL_connect:SSLv3 read server certificate request A

Sono sorpreso che semplicemente usando:

openssl s_client -connect pokyloky.com:5222 

non indica direttamente che è stato richiesto un certificato client. C'è un errore di handshake:

139843101763232:error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure:s3_pkt.c:1262:SSL alert number 40
139843101763232:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:177:

Ma non indica esplicitamente perché la stretta di mano ha fallito.

Perché openssl s_connect non indica chiaramente che il server ha richiesto un certificato e l'handshake non è riuscito a causa di questo?

    
posta Cybergibbons 30.09.2015 - 11:51
fonte

2 risposte

3

Quel comportamento non fa parte di TLS v1.2

But it doesn't explicitly state why the handshake has failed.

Non può. Non è definito come parte del protocollo (TLS v1.2).

Quando il server o il client decidono di interrompere una connessione, possono scegliere tra uno dei diversi messaggi alert .

Un messaggio di Alert ha un aspetto simile a questo :

struct {
      AlertLevel level;
      AlertDescription description;
} Alert;

AlertLevel ha una larghezza di un byte e ha solo due stati:

enum { warning(1), fatal(2), (255) } AlertLevel;

E AlertDescription è anch'essa larga un byte. Ma dei 256 possibili motivi, solo 30 vengono assegnati e utilizzati . E di questi 30, semplicemente non ce n'è, che si adatta a "Ehi, ti ho detto che volevo un certificato client, perché non me ne hai dato uno?!?" -bill.

(E anche se sembra che possa andare bene, no_certificate_RESERVED(41) è stato usato per qualcos'altro. Ovvero in SSLv3.0 è stato usato per l'altra direzione: per il CLIENTE per dire al server "Scusa, posso Ti diamo un certificato client. ")

Ora per la domanda più profonda "Non avrebbe senso definire un tale codice di motivazione se ci sono ancora molti punti inutilizzati nel codice? Invece di solo un fallimento difficile, in gran parte inspiegabile?" la mia risposta è semplicemente: "Non lo so."

Non vedo come un tale avviso possa rendere il protocollo più debole, ma la crittografia è complicata e non ne sono sicuro.

Loadbalancer per dare un messaggio di errore amichevole

Ma cosa succede se vuoi dare un messaggio di errore amichevole?

AFAIK, quindi devi fare cose un po 'complicate con la logica loadbalancer e solo inizialmente consentire la connessione clientcert-less, ma poi reindirizzare immediatamente a una pagina di errore. Apache può fare una cosa del genere con una regola simile a questa :

RewriteCond %{SSL:SSL_CLIENT_VERIFY} !^SUCCESS$
RewriteRule .* /help/ssl-client-auth-required.html [L]

IIS definisce un messaggio eror HTTP chiamato 403.7 Forbidden: Client Certificate Required . Penso che questa sia una mossa intelligente (meglio che fallire, almeno), anche se il .7 di 403.7 non è standard e penso che il messaggio di errore appartenga al livello TLS e non al livello HTTP.

    
risposta data 29.11.2015 - 15:20
fonte
1

Puoi visualizzare l'output dettagliato del protocollo aggiungendo il flag -trace . La documentazione afferma che:

-trace

show verbose trace output of protocol messages. OpenSSL needs to be compiled with enable-ssl-trace for this option to work.

Puoi, ovviamente, utilizzare i flag -state , -debug e -msg per recuperare informazioni estese su come il protocollo selezionato funziona così come lo stato openssl passa attraverso:

-state

prints out the SSL session states.

-debug

print extensive debugging information including a hex dump of all traffic.

-msg

show all protocol messages with hex dump.
    
risposta data 30.09.2015 - 13:11
fonte

Leggi altre domande sui tag