RFC 2818 - HTTP Over TLS (HTTPS) - 2. HTTP su TLS (HTTP Over TLS)
2. HTTP su TLS (HTTP Over TLS)
Principio centrale
Concettualmente molto semplice: HTTP/TLS è molto semplice. Utilizzare HTTP su TLS esattamente come si userebbe HTTP su TCP.
2.1. Connection Initiation (Avvio della connessione)
Processo:
1. Client → Server: Stabilire connessione TCP (porta 443)
2. Client → Server: Inviare TLS ClientHello
3. ↔ Processo di handshake TLS ↔
4. Dopo il completamento dell'handshake: Il client può avviare la prima richiesta HTTP
Requisiti:
- ✅ Il client HTTP deve (MUST) agire come client TLS
- ✅ Connettersi alla porta appropriata (predefinita 443)
- ✅ Inviare TLS ClientHello per iniziare l'handshake
- ✅ Tutti i dati HTTP devono (MUST) essere inviati come "dati applicazione" TLS
Esempio di flusso:
Client:
1. Connessione TCP a www.example.com:443
2. Inviare ClientHello
Server:
3. Rispondere ServerHello + Certificato
4. ServerHelloDone
Client:
5. ClientKeyExchange
6. ChangeCipherSpec
7. Finished
Server:
8. ChangeCipherSpec
9. Finished
← Handshake TLS completato →
Client:
10. Inviare richiesta HTTP crittografata:
GET / HTTP/1.1
Host: www.example.com
2.2. Connection Closure (Chiusura della connessione)
TLS fornisce una funzionalità per la chiusura sicura delle connessioni.
Closure Alert (Avviso di chiusura)
Definizioni:
- Chiusura valida (Valid Closure): Avviso di chiusura corretto ricevuto
- Chiusura incompleta (Incomplete Close): Chiudere la connessione immediatamente dopo l'invio dell'avviso di chiusura
- Chiusura prematura (Premature Close): Connessione chiusa senza ricevere l'avviso di chiusura
Requisiti:
- ✅ Le implementazioni devono (MUST) avviare uno scambio di avvisi di chiusura prima di chiudere una connessione
- ⚠️ Le implementazioni possono (MAY) chiudere la connessione dopo aver inviato l'avviso di chiusura (senza attendere)
- ❌ Le connessioni con chiusura prematura non devono (MUST NOT) riutilizzare la sessione
2.2.1. Client Behavior (Comportamento del client)
Problema: HTTP utilizza la chiusura della connessione per segnalare la fine dei dati del server.
Il client deve (MUST):
- ✅ Trattare qualsiasi chiusura prematura come errore
- ✅ Trattare i dati ricevuti come potenzialmente troncati
- ✅ Inviare avviso di chiusura prima di chiudere la connessione
Casi speciali:
- Risposta senza Content-Length:
HTTP/1.1 200 OK
Content-Type: text/html
[La chiusura della connessione indica la fine]
← La chiusura prematura non può distinguere il server dall'attaccante →
- Content-Length presente ma non completamente letto:
HTTP/1.1 200 OK
Content-Length: 1000
[Solo 500 byte ricevuti prima della chiusura]
← Non può determinare se è un errore del server o un attacco →
Eccezione: Se i dati ricevuti corrispondono a Content-Length, dovrebbe (SHOULD) essere trattato come completato.
Esempio client:
✅ Chiusura normale:
Client: Inviare closure_alert
Attendere closure_alert del server
Chiudere la connessione
⚡ Chiusura rapida:
Client: Inviare closure_alert
Chiudere la connessione immediatamente (non attendere)
← Questo genera una chiusura incompleta lato server →
2.2.2. Server Behavior (Comportamento del server)
Requisito RFC 2616: I server devono (MUST) riprendersi correttamente dalla chiusura del client.
Il server dovrebbe (SHOULD):
- ✅ Essere preparato a ricevere una chiusura incompleta dal client
- ✅ Essere disposto a riprendere le sessioni TLS chiuse in questo modo
- ✅ Tentare di scambiare avvisi di chiusura con il client
- ⚡ Può (MAY) chiudere la connessione dopo aver inviato l'avviso di chiusura
Nota di implementazione:
HTTP senza connessioni persistenti:
- Il server segnala la fine dei dati chiudendo la connessione
- Ma il client potrebbe aver già inviato l'avviso di chiusura e disconnesso
2.3. Port Number (Numero di porta)
Porta predefinita: 443
Motivazione:
Il server HTTP si aspetta: Request-Line (ad es. GET / HTTP/1.1)
Il server TLS si aspetta: ClientHello
← Non può distinguere sulla stessa porta →
Soluzione: Utilizzare porte diverse
- HTTP: 80
- HTTPS: 443
Esempi:
# HTTP (testo in chiaro)
curl http://www.example.com:80/
# HTTPS (crittografato)
curl https://www.example.com:443/
2.4. URI Format (Formato URI)
Identificatore di protocollo: https:// (invece di http://)
Esempi:
https://www.example.com/~smith/home.html
https://api.example.com:8443/v1/users
https://192.168.1.1/admin
Componenti URI:
https://www.example.com:443/path?query#fragment
↑ ↑ ↑ ↑ ↑ ↑
scheme host port path query fragment