Come si verifica che un certificato appartenga a un dominio?

4

Sto utilizzando PHP e sto provando a verificare che un certificato SSL appartenga al dominio / IP SMTP a cui mi sto collegando.

Attualmente posso verificare che il certificato sia valido utilizzando il seguente codice

$resource = fsockopen( "tcp://mail.example.com", 25, $errno, $errstr ); 

...

stream_set_blocking($resource, true);

stream_context_set_option($resource, 'ssl', 'verify_host', true);
stream_context_set_option($resource, 'ssl', 'verify_peer', true);
stream_context_set_option($resource, 'ssl', 'allow_self_signed', false);

stream_context_set_option($resource, 'ssl', 'cafile', __DIR__ . '/cacert.pem');

$secure = stream_socket_enable_crypto($resource, true, STREAM_CRYPTO_METHOD_TLS_CLIENT);
stream_set_blocking($resource, false);

if( ! $secure)
{
    die("failed to connect securely\n");
}

In base alla documentazione sembra che devo fare qualcosa di simile.

stream_context_set_option($resource, 'ssl', 'SNI_enabled', true);
stream_context_set_option($resource, 'ssl', 'SNI_server_name', 'expected.example.com');

Come faccio a verificare che il server che sto collegando abbia un certificato valido per expected.example.com ? Devo prima fare un controllo rDNS? Cosa succede se il DNS è stato alterato da un attacco MITM?

    
posta Xeoncross 17.11.2012 - 20:49
fonte

3 risposte

5

SNI è Indicazione del nome del server ; non fa parte di alcuna verifica . Un client usa SNI per informare il server sul nome che il client sta cercando di raggiungere; il nome viene inviato nei primi passaggi dell'handshake SSL. Questo ha lo scopo di supportare più server (cioè più nomi ) che condividono lo stesso indirizzo IP: l'SNI dice al server quale certificato deve usare per questa particolare connessione.

Questa scelta del certificato è importante perché i client si aspettano che il certificato del server contenga il nome che desiderano raggiungere. E questa "aspettativa" è esattamente ciò che dovresti fare: devi informare la tua implementazione SSL che vuoi raggiungere un server con un nome specifico ( mail.example.com , apparentemente) e che il certificato del server DEVE contenere quel nome (questo è cruciale : senza questo test, un utente malintenzionato attivo potrebbe fornirti il proprio certificato e dirottare in silenzio la connessione). Sembra che ciò sia fatto con l'opzione CN_match .

(Naturalmente puoi usare SNI, è anche raccomandato perché può davvero aiutare il server, ma questo non è SNI che ti protegge dagli attacchi MitM.)

    
risposta data 04.12.2012 - 01:53
fonte
3

Il modo tipico per definire la validità è una serie di controlli - a volte i controlli successivi vengono saltati, se il rischio di non eseguirli è ritenuto sufficientemente basso.

  1. C'è una prova che il mittente ha il controllo della chiave privata - in una transazione SSL, questa viene gestita come parte dell'handshake.

  2. Il certificato è costruito e firmato correttamente - ha un valore valido firma - Scommetto che la riga di comando per "verify_peer" compie questo (qualifica - non l'ho mai fatto in PHP)

  3. Il certificato è firmato da una fonte attendibile - significa che non è possibile utilizzare un certificato autofirmato senza averne memorizzato una copia nella cache. In genere è necessario eseguire il provisioning del server con una raccolta di CA attendibili. Probabilmente coperto dal riferimento ai comandi che allow_self_signed è falso.

  4. Il certificato non è scaduto - il controllo della data di validità lo farà. Non sei sicuro che qualcuno del tuo codice stia facendo questo: non è un dato, devi testarlo e controllare la documentazione più profondamente.

  5. Il certificato ha una buona reputazione (non revocata) con la CA emittente - comporta il controllo del CRL della CA o l'esecuzione di una richiesta OCSP. La CA revocherà il certificato se c'è motivo di dubitare che la coppia di chiavi resti privata della fonte. Non vedo alcun codice nella libreria che lo fornisce. Non è insolito - più volte ho dovuto avere gruppi con cui lavoro con librerie aggiuntive per aggiungere questo check in. Questo è dove molti sviluppatori web iniziano a saltare i passaggi del rischio è abbastanza basso.

Come aggiunta: alcune norme di sicurezza impongono che il certificato rappresenti correttamente il server che lo fornisce. Per un server web, in genere questo è il nome comune (CN) del certificato che corrisponde al DNS dell'host che si sta contattando (vedere link per un esempio). Altri sistemi possono anche controllare il Nome alt soggetto (disponibile anche nel certificato di Google, ad esempio).

Questo non è totalmente standardizzato. Le RFC descrivono i potenziali usi e formati di questi campi, ma è compito della politica di sicurezza della tua entità indicare chiaramente ciò che è richiesto qui.

Tipicamente per questo tipo di controllo, ho:

  • Ha avuto accesso al DNS desiderato per la connessione
  • Effettuata la connessione, ottenuto il certificato
  • Estratto il certificato dalla connessione e verificato che il CN o il nome alt soggetto corrispondessero a ciò che avevo chiesto originariamente nel primo passaggio.

Questo, combinato con la CA attendibile è sufficiente per verificare che:

  • un'entità di cui ti fidi
  • verificato che hai ottenuto ciò che hai richiesto

Il passaggio 4 dell'elenco sopra riportato fornisce la garanzia che nel tempo tra la CA che rilascia il certificato e ora non è cambiato nulla.

    
risposta data 14.05.2013 - 19:21
fonte
2

Fare questo te stesso è pieno di problemi. Quello che è stato menzionato è che è necessario verificare se il certificato è stato revocato, il che implica contattare l'autorità di certificazione attendibile. E rifiutando il certificato se quel contatto fallisce. Un altro è che il nome comune nel certificato è una sequenza di byte, che può includere zero byte. Ad esempio, quando si contatta www.amazon.com si prevede che il nome comune sia 14 byte. Potrebbe essere più byte, con il byte # 14 zero - un attacco che molte implementazioni non sono riuscite a rilevare. Molto meglio usare una libreria che viene regolarmente aggiornata.

    
risposta data 15.03.2014 - 13:39
fonte

Leggi altre domande sui tag