3. Log Format and Operation (Formato e funzionamento del log)
3. Log Format and Operation (Formato e funzionamento del log)
Chiunque può inviare certificati ai certificate logs per la verifica pubblica; tuttavia, poiché i certificati non saranno accettati dai client TLS se non registrati, ci si attende che i titolari dei certificati o le loro CA li inviino di solito. Un log è un singolo Merkle Tree sempre crescente e append-only di tali certificati.
Quando un certificato valido viene inviato a un log, il log DEVE restituire immediatamente un Signed Certificate Timestamp (SCT) (timestamp di certificato firmato). L'SCT è la promessa del log di incorporare il certificato nel Merkle Tree entro un intervallo di tempo fisso noto come Maximum Merge Delay (MMD) (ritardo massimo di fusione). Se il log ha già visto il certificato, PUÒ restituire lo stesso SCT che aveva restituito in precedenza. I server TLS DEVONO presentare un SCT da uno o più log al client TLS insieme al certificato. I client TLS DEVONO rifiutare certificati che non hanno un SCT valido per il certificato end-entity (entità finale).
Periodicamente, ciascun log aggiunge tutte le sue nuove voci al Merkle Tree e firma la radice dell'albero. I verificatori possono così verificare che ogni certificato per cui è stato emesso un SCT compaia effettivamente nel log. Il log DEVE incorporare un certificato nel suo Merkle Tree entro il periodo Maximum Merge Delay dopo l'emissione dell'SCT.
Gli operatori di log NON DEVONO imporre condizioni sul recupero o sulla condivisione dei dati dal log.
3.1 Log Entries (Voci del log)
Chiunque può inviare un certificato a qualsiasi log. Per consentire l'attribuzione di ciascun certificato registrato al suo emittente, il log DEVE pubblicare una lista di acceptable root certificates (certificati radice accettabili) (tale lista può utilmente essere l'unione dei certificati radice fidati dai principali fornitori di browser). Ogni certificato inviato DEVE essere accompagnato da tutti i certificati aggiuntivi richiesti per verificare la catena fino a un certificato radice accettato. Il certificato radice stesso PUÒ essere omesso dalla catena inviata al log server.
In alternativa, le certificate authorities (CA) (radice così come intermedie) possono inviare un certificato ai log prima dell'emissione. Per farlo, la CA invia un Precertificate (precertificato) che il log può usare per creare una voce che sarà valida rispetto al certificato emesso. Il Precertificate è costruito dal certificato da emettere aggiungendo una special critical poison extension (estensione critica «velenosa») (OID 1.3.6.1.4.1.11129.2.4.3, il cui extnValue OCTET STRING contiene dati ASN.1 NULL (0x05 0x00)) al TBSCertificate end-entity (questa estensione serve a garantire che il Precertificate non possa essere validato da un client X.509v3 standard) e firmando il TBSCertificate risultante [RFC5280] con
-
un Precertificate Signing Certificate (certificato di firma del precertificato) speciale (CA:true, Extended Key Usage: Certificate Transparency, OID 1.3.6.1.4.1.11129.2.4.4). Il Precertificate Signing Certificate DEVE essere certificato direttamente dal certificato CA (radice o intermedia) che in ultima analisi firmerà il TBSCertificate end-entity producendo il certificato end-entity (si noti che il log può rilassare le regole di validazione standard per consentire ciò, purché il certificato emesso sarà valido),
-
oppure, il certificato CA che firmerà il certificato finale.
Come sopra, l'invio del Precertificate DEVE essere accompagnato dal Precertificate Signing Certificate, se usato, e da tutti i certificati aggiuntivi richiesti per verificare la catena fino a un certificato radice accettato. La firma sul TBSCertificate indica l'intento dell'autorità di certificazione di emettere un certificato. Tale intento è considerato vincolante (cioè, l'emissione errata del Precertificate è considerata equivalente all'emissione errata del certificato finale). Ogni log verifica la catena di firma del Precertificate ed emette un Signed Certificate Timestamp sul TBSCertificate corrispondente.
I log DEVONO verificare che il certificato end-entity o il Precertificate inviato abbia una catena di firma valida che risalga a un trusted root CA certificate (certificato CA radice fidato), usando la catena di certificati CA intermedî fornita dall'inviatore. I log POSSONO accettare certificati scaduti, non ancora validi, revocati o altrimenti non pienamente validi secondo le regole di verifica X.509 per accomodare particolarità del software di emissione delle CA. Tuttavia, i log DEVONO rifiutare di pubblicare certificati senza una catena valida verso una CA radice nota. Se un certificato è accettato e viene emesso un SCT, il log accettante DEVE memorizzare l'intera catena usata per la verifica, incluso il certificato o Precertificate stesso e incluso il certificato radice usato per verificare la catena (anche se era stato omesso dall'invio), e DEVE presentare questa catena per la verifica su richiesta. Questa catena è necessaria per impedire a una CA di eludere la responsabilità registrando una catena parziale o vuota. (Nota: ciò esclude effettivamente certificati self-signed e basati su DANE finché non si trova un meccanismo per controllare lo spam per tali certificati. Gli autori accettano suggerimenti.)
Ogni certificate entry (voce di certificato) in un log DEVE includere i seguenti componenti:
enum { x509_entry(0), precert_entry(1), (65535) } LogEntryType;
struct {
LogEntryType entry_type;
select (entry_type) {
case x509_entry: X509ChainEntry;
case precert_entry: PrecertChainEntry;
} entry;
} LogEntry;
opaque ASN.1Cert<1..2^24-1>;
struct {
ASN.1Cert leaf_certificate;
ASN.1Cert certificate_chain<0..2^24-1>;
} X509ChainEntry;
struct {
ASN.1Cert pre_certificate;
ASN.1Cert precertificate_chain<0..2^24-1>;
} PrecertChainEntry;
I log POSSONO limitare la lunghezza della catena che accetteranno.
"entry_type" è il tipo di questa voce. Revisioni future di questa versione di protocollo possono aggiungere nuovi valori LogEntryType. La Sezione 4 spiega come i client dovrebbero gestire tipi di voce sconosciuti.
"leaf_certificate" è il certificato end-entity inviato per la verifica.
"certificate_chain" è una catena di certificati aggiuntivi richiesti per verificare il certificato end-entity. Il primo certificato DEVE certificare il certificato end-entity. Ogni certificato successivo DEVE certificare direttamente quello che lo precede. Il certificato finale DEVE essere un certificato radice accettato dal log.
"pre_certificate" è il Precertificate inviato per la verifica.
"precertificate_chain" è una catena di certificati aggiuntivi richiesti per verificare l'invio del Precertificate. Il primo certificato PUÒ essere un Precertificate Signing Certificate valido e DEVE certificare il Precertificate. Ogni certificato successivo DEVE certificare direttamente quello che lo precede. Il certificato finale DEVE essere un certificato radice accettato dal log.
3.2 Structure of the Signed Certificate Timestamp (Struttura dell'SCT)
enum { certificate_timestamp(0), tree_hash(1), (255) }
SignatureType;
enum { v1(0), (255) }
Version;
struct {
opaque key_id[32];
} LogID;
opaque TBSCertificate<1..2^24-1>;
struct {
opaque issuer_key_hash[32];
TBSCertificate tbs_certificate;
} PreCert;
opaque CtExtensions<0..2^16-1>;
"key_id" è l'hash SHA-256 della chiave pubblica del log, calcolato sulla codifica DER della chiave rappresentata come SubjectPublicKeyInfo.
"issuer_key_hash" è l'hash SHA-256 della chiave pubblica dell'emittente del certificato, calcolato sulla codifica DER della chiave rappresentata come SubjectPublicKeyInfo. Ciò è necessario per legare l'emittente al certificato finale.
"tbs_certificate" è il TBSCertificate codificato in DER (vedere [RFC5280]) componente del Precertificate, cioè senza la firma e senza l'estensione poison. Se il Precertificate non è firmato con il certificato CA che emetterà il certificato finale, allora il TBSCertificate ha anche il suo emittente modificato a quello della CA che emetterà il certificato finale. Si noti che è anche possibile ricostruire questo TBSCertificate dal certificato finale estraendo il TBSCertificate da esso ed eliminando l'estensione SCT. Si noti inoltre che, poiché il TBSCertificate contiene un AlgorithmIdentifier che DEVE corrispondere sia all'algoritmo di firma del Precertificate sia a quello del certificato finale, DEVONO essere firmati con lo stesso algoritmo e gli stessi parametri. Se il Precertificate è emesso usando un Precertificate Signing Certificate ed è presente un'estensione Authority Key Identifier nel TBSCertificate, l'estensione corrispondente DEVE essere presente anche nel Precertificate Signing Certificate; in questo caso, il TBSCertificate ha anche il suo Authority Key Identifier modificato per corrispondere all'emittente finale.
struct {
Version sct_version;
LogID id;
uint64 timestamp;
CtExtensions extensions;
digitally-signed struct {
Version sct_version;
SignatureType signature_type = certificate_timestamp;
uint64 timestamp;
LogEntryType entry_type;
select(entry_type) {
case x509_entry: ASN.1Cert;
case precert_entry: PreCert;
} signed_entry;
CtExtensions extensions;
};
} SignedCertificateTimestamp;
La codifica dell'elemento digitally-signed è definita in [RFC5246].
"sct_version" è la versione del protocollo cui l'SCT è conforme. Questa versione è v1.
"timestamp" è l'NTP Time [RFC5905] corrente, misurata dall'epoch (1 gennaio 1970, 00:00), ignorando i leap seconds, in millisecondi.
"entry_type" può essere implicito dal contesto in cui l'SCT è presentato.
"signed_entry" è il "leaf_certificate" (nel caso di un X509ChainEntry) oppure il PreCert (nel caso di un PrecertChainEntry), come descritto sopra.
"extensions" sono estensioni future a questa versione di protocollo (v1). Attualmente non sono specificate estensioni.
3.3 Including the Signed Certificate Timestamp in the TLS Handshake (SCT nell'handshake TLS)
I dati SCT corrispondenti al certificato end-entity da almeno un log DEVONO essere inclusi nell'handshake TLS, sia usando un'estensione certificato X509v3 come descritto sotto, sia usando un'estensione TLS (Sezione 7.4.1.4 di [RFC5246]) con tipo "signed_certificate_timestamp", sia usando Online Certificate Status Protocol (OCSP) Stapling (nota anche come estensione TLS "Certificate Status Request"; vedere [RFC6066]), dove la risposta include un'estensione OCSP con OID 1.3.6.1.4.1.11129.2.4.5 (vedere [RFC2560]) e corpo:
SignedCertificateTimestampList ::= OCTET STRING
Almeno un SCT DEVE essere incluso. Gli operatori del server POSSONO includere più di un SCT.
Allo stesso modo, un'autorità di certificazione PUÒ inviare un Precertificate a più di un log, e tutti gli SCT ottenuti possono essere incorporati direttamente nel certificato finale, codificando la struttura SignedCertificateTimestampList come OCTET STRING ASN.1 e inserendo i dati risultanti nel TBSCertificate come estensione certificato X509v3 (OID 1.3.6.1.4.1.11129.2.4.2). Alla ricezione del certificato, i client possono ricostruire il TBSCertificate originale per verificare la firma dell'SCT.
Il contenuto dell'OCTET STRING ASN.1 incorporato in un'estensione OCSP o in un'estensione certificato X509v3 è il seguente:
opaque SerializedSCT<1..2^16-1>;
struct {
SerializedSCT sct_list <1..2^16-1>;
} SignedCertificateTimestampList;
Qui, "SerializedSCT" è una stringa di byte opaca che contiene la struttura TLS serializzata. Questa codifica assicura che i client TLS possano decodificare ogni SCT individualmente (cioè, se c'è un aggiornamento di versione, i client obsoleti possono ancora analizzare i vecchi SCT saltando i nuovi SCT le cui versioni non comprendono).
Allo stesso modo, gli SCT possono essere incorporati in un'estensione TLS. Vedere sotto per i dettagli.
I client TLS DEVONO implementare tutti e tre i meccanismi. I server DEVONO implementare almeno uno dei tre meccanismi. Si noti che i server TLS esistenti possono in genere usare il meccanismo dell'estensione certificato senza modifiche.
I server TLS dovrebbero inviare SCT da più log nel caso in cui uno o più log non siano accettabili per il client (ad esempio, se un log è stato radiato per comportamento scorretto o ha subito un compromissione della chiave).
3.3.1 TLS Extension (Estensione TLS)
L'SCT può essere inviato durante l'handshake TLS usando un'estensione TLS con tipo "signed_certificate_timestamp".
I client che supportano l'estensione DOVREBBE inviare un'estensione ClientHello con il tipo appropriato e "extension_data" vuoto.
I server DEVONO inviare SCT solo ai client che hanno indicato supporto per l'estensione nel ClientHello, nel qual caso gli SCT sono inviati impostando "extension_data" a "SignedCertificateTimestampList".
La ripresa di sessione usa le informazioni della sessione originale: i client DOVREBBE includere il tipo di estensione nel ClientHello, ma se la sessione è ripresa, non ci si attende che il server la elabori o includa l'estensione nel ServerHello.
3.4 Merkle Tree (Albero Merkle)
L'algoritmo di hash per il Merkle Tree Hash è SHA-256.
Struttura dell'input del Merkle Tree:
enum { timestamped_entry(0), (255) }
MerkleLeafType;
struct {
uint64 timestamp;
LogEntryType entry_type;
select (entry_type) {
case x509_entry: ASN.1Cert;
case precert_entry: PreCert;
} signed_entry;
CtExtensions extensions;
} TimestampedEntry;
struct {
Version version;
MerkleLeafType leaf_type;
select (leaf_type) {
case timestamped_entry: TimestampedEntry;
}
} MerkleTreeLeaf;
Qui, "version" è la versione del protocollo cui MerkleTreeLeaf corrisponde. Questa versione è v1.
"leaf_type" è il tipo dell'input foglia. Attualmente è definito solo "timestamped_entry" (corrispondente a un SCT). Revisioni future di questa versione di protocollo possono aggiungere nuovi tipi MerkleLeafType. La Sezione 4 spiega come i client dovrebbero gestire tipi di foglia sconosciuti.
"timestamp" è il timestamp dell'SCT corrispondente emesso per questo certificato.
"signed_entry" è il "signed_entry" dell'SCT corrispondente.
"extensions" sono le "extensions" dell'SCT corrispondente.
Le foglie del Merkle Tree sono i leaf hash delle strutture "MerkleTreeLeaf" corrispondenti.
3.5 Signed Tree Head (Testa firmata dell'albero)
Ogni volta che un log aggiunge nuove voci all'albero, il log DOVREBBE firmare l'hash dell'albero corrispondente e le informazioni sull'albero (vedere il messaggio client Signed Tree Head corrispondente nella Sezione 4.3). La firma per tali dati è strutturata come segue:
digitally-signed struct {
Version version;
SignatureType signature_type = tree_hash;
uint64 timestamp;
uint64 tree_size;
opaque sha256_root_hash[32];
} TreeHeadSignature;
"version" è la versione del protocollo cui TreeHeadSignature è conforme. Questa versione è v1.
"timestamp" è l'ora corrente. Il timestamp DEVE essere almeno recente come il timestamp SCT più recente nell'albero. Ogni timestamp successivo DEVE essere più recente del timestamp dell'aggiornamento precedente.
"tree_size" è uguale al numero di voci nel nuovo albero.
"sha256_root_hash" è la radice del Merkle Hash Tree.
Ogni log DEVE produrre su richiesta una Signed Tree Head (STH) non più vecchia del Maximum Merge Delay. Nell'improbabile evento che non riceva nuovi invii durante un periodo MMD, il log DEVE firmare lo stesso Merkle Tree Hash con un timestamp aggiornato.