SSL.RO
Documentație SSL.RO · RFC 9162

Certificate Transparency v2.0

RFC 9162 descrie protocolul prin care certificatele TLS sunt publicate în jurnale verificabile, auditate și monitorizate pentru emiteri neașteptate.

RFC
9162
Versiune 2.0Statut ExperimentalPublicat 2021Înlocuiește RFC 6962
Ce este un certificat?

O dovadă digitală care leagă un nume de domeniu de o cheie publică și permite HTTPS.

Ce face CT?

Publică emiterile în jurnale verificabile, astfel încât proprietarii și monitorii să le poată observa.

De ce contează?

Un certificat neașteptat poate fi investigat chiar dacă site-ul nu îl servește în acest moment.

Textul tehnic de mai jos păstrează structurile TLS/ASN.1, formulele și numele câmpurilor din RFC 9162 pentru compatibilitate și precizie. Informațiile despre starea curentă a documentului, erate și transmiterea feedbackului sunt disponibile în sursa oficială RFC Editor.

Cuprins

01

Rezumat

Acest document descrie versiunea 2.0 a protocolului Transparența Certificatelor (Certificate Transparency, CT), destinat înregistrării publice a existenței certificatelor TLS de server pe măsură ce sunt emise sau observate, într-un mod care permite oricui să auditeze activitatea autorităților de certificare (CA), să observe emiterea de certificate suspecte și să auditeze chiar și jurnalele de certificate. Intenția este ca, în final, clienții să refuze certificatelor care nu apar într-un jurnal, ceea ce ar obliga efectiv autoritățile de certificare să adauge toate certificatele emise în jurnale.

Acest document înlocuiește (obsoletes) RFC 6962. El specifică, de asemenea, o nouă extensie TLS folosită pentru transmiterea diverselor artefacte CT.

Jurnalele sunt servicii de rețea care implementează operațiunile de protocol pentru trimitere (submissions) și interogări definite în acest document.

02

Starea acestui document

Acest document nu este o specificație a Internet Standards Track; este publicat pentru examinare, implementare experimentală și evaluare.

Documentul definește un Protocol Experimental pentru comunitatea Internet. Este un produs al Internet Engineering Task Force (IETF) și reprezintă consensul comunității IETF. A fost supus revizuirii publice și a fost aprobat pentru publicare de Internet Engineering Steering Group (IESG). Nu toate documentele aprobate de IESG sunt candidate pentru orice nivel de Internet Standard; vezi Secțiunea 2 din RFC 7841.

Informații despre starea curentă a documentului, erate și cum să transmiți feedback sunt disponibile la https://www.rfc-editor.org/info/rfc9162.

03

Introducere

Transparența Certificatelor urmărește să atenueze problema certificatelor emise în mod fraudulos (misissued), oferind jurnale append-only (cu adăugare doar la final) ale certificatelor emise. Jurnalele nu împiedică ele însele emiterea frauduloasă, dar asigură că părțile interesate (în special cele menționate în certificate) pot detecta o astfel de emitere. Este un mecanism general, care ar putea fi folosit pentru înregistrarea transparentă a oricărei forme de date binare, sub rezerva unor criterii de includere. Acest document descrie doar utilizarea pentru certificatele TLS publice de server (adică atunci când criteriul de includere este un certificat valid emis de o autoritate de certificare publică). O definiție tipică a termenului „public” se găsește în [CABBR].

Fiecare jurnal conține lanțuri de certificate, care pot fi trimise de oricine. Se așteaptă ca autoritățile de certificare publice să contribuie cu toate certificatele nou emise la unul sau mai multe jurnale; pot contribui însă și deținătorii de certificate sau terțe părți. Pentru ca jurnalele să nu devină inutile din cauza unui număr mare de certificate false, fiecare lanț trebuie să se termine cu o ancoră de încredere (trust anchor) acceptată de jurnal. Jurnalul poate limita și lungimea lanțului acceptat; astfel de lanțuri trebuie să se termine și ele cu o ancoră de încredere acceptată. Când un lanț este acceptat de jurnal, se returnează o marcă temporală semnată (signed timestamp), care poate fi folosită ulterior ca dovadă pentru clienții TLS că lanțul a fost trimis. Clienții TLS pot astfel cere ca toate certificatele pe care le acceptă drept valide să fie însoțite de mărci temporale semnate.

Cei care sunt îngrijorați de emiterea frauduloasă pot monitoriza jurnalele, interogându-le periodic pentru toate noile înregistrări, și pot verifica dacă domeniile de care răspund au primit certificate neașteptate. Ce fac cu aceste informații, în special când descoperă o emitere frauduloasă, depășește scopul acestui document. În linii mari, pot invoca mecanismele de afaceri existente pentru certificatele emise fraudulos: colaborarea cu CA pentru revocare sau cu întreținătorii listelor de ancore de încredere pentru eliminarea CA. Desigur, oricine poate monitoriza jurnalele și poate acționa cum consideră.

Similar, cei care au primit mărci temporale semnate de la un anumit jurnal pot cere ulterior o dovadă de includere (proof of inclusion) de la acel jurnal. Dacă jurnalul nu poate oferi dovada (sau certificatul corespunzător lipsește din copiile monitorilor), aceasta este o dovadă a funcționării incorecte a jurnalului. Verificarea este asincronă, pentru ca clienții să poată continua fără întârziere, în ciuda unor posibile probleme, cum ar fi conectivitatea de rețea sau capriciile firewall-urilor.

Proprietatea append-only a fiecărui jurnal este realizată cu ajutorul arborilor Merkle, care pot demonstra eficient că orice instanță a jurnalului este o supra-mulțime a oricărei instanțe anterioare și pot detecta eficient diverse comportamente greșite (de exemplu, emiterea unei mărci temporale pentru un certificat care nu este ulterior înregistrat).

Mecanismele de audit descrise aici pot fi ocolite de un jurnal rău-intenționat care prezintă vederi diferite, inconsistente, unor clienți diferiți. Prin urmare, este necesar să tratăm fiecare jurnal ca pe o terță parte de încredere. Deși se dezvoltă mecanisme pentru a remedia aceste lipsuri și a evita necesitatea de a avea încredere oarbă în jurnale, astfel de mecanisme sunt în afara scopului acestui document.

1.1. Limbajul cerințelor

Cuvintele-cheie „MUST”, „MUST NOT”, „REQUIRED”, „SHALL”, „SHALL NOT”, „SHOULD”, „SHOULD NOT”, „RECOMMENDED”, „NOT RECOMMENDED”, „MAY” și „OPTIONAL” din acest document trebuie interpretate conform BCP 14 [RFC2119] [RFC8174] atunci și numai atunci când apar cu litere mari, exact cum sunt prezentate aici. Echivalentele folosite în acest document sunt: trebuie (MUST/REQUIRED/SHALL), nu trebuie (MUST NOT/SHALL NOT), ar trebui (SHOULD), nu ar trebui (SHOULD NOT), recomandat / nerecomandat (RECOMMENDED / NOT RECOMMENDED), poate (MAY) și opțional (OPTIONAL).

1.2. Structuri de date

Structurile de date sunt definite și codificate conform convențiilor din Secțiunea 3 a [RFC8446].

Acest document folosește identificatori de obiect (OID) pentru identificarea ID-urilor de jurnal (Secțiunea 4.4), pentru tipul eContentType CMS al precertificatului (Secțiunea 3.2), pentru extensiile X.509v3 din certificate (Secțiunea 7.1.2) și pentru răspunsurile OCSP (Secțiunea 7.1.1). OID-urile sunt definite într-un arc ales datorită codificării scurte.

1.3. Diferențele principale față de CT 1.0

Acest document revizuiește și înlocuiește protocolul CT 1.0 [RFC6962], folosind lecțiile din implementările CT 1.0 și feedback-ul comunității. Principalele modificări:

04

Componente criptografice

2.1. Arborii Merkle

O descriere completă a arborelui Merkle depășește scopul acestui document. Pe scurt, este un arbore binar în care fiecare nod care nu este frunză este un hash al copiilor săi. Pentru CT, numărul de copii este de cel mult doi. Informații suplimentare se găsesc în secțiunile Introduction și Reference din [RFC8391].

2.1.1. Definiția arborelui Merkle

Jurnalul folosește un arbore Merkle binar pentru auditare eficientă. Algoritmul de hash folosit este unul dintre parametrii jurnalului (Secțiunea 4.1). Documentul stabilește un registru al algoritmilor de hash acceptați (Secțiunea 10.2.1). De-a lungul documentului, algoritmul de hash folosit este numit HASH, iar dimensiunea ieșirii sale în octeți, HASH_SIZE. Intrarea în Merkle Tree Hash este o listă de înregistrări de date; acestea sunt supuse hash-ului pentru a forma frunzele arborelui. Ieșirea este un singur Merkle Tree Hash de dimensiune HASH_SIZE. Fiind dată o listă ordonată de n intrări, D_n = {d[0], d[1], ..., d[n-1]}, Merkle Tree Hash (MTH) este definit astfel:

MTH({}) = HASH().
MTH({d[0]}) = HASH(0x00 || d[0]).

Pentru n > 1, fie k cea mai mare putere a lui 2 mai mică decât n (k < n ≤ 2k):
MTH(D_n) = HASH(0x01 || MTH(D[0:k]) || MTH(D[k:n])),

unde || denotă concatenare, : denotă concatenarea listelor, iar D[k1:k2] = D'_(k2-k1) denotă lista {d'[0] = d[k1], d'[1] = d[k1+1], ..., d'[k2-k1-1] = d[k2-1]} de lungime (k2 - k1).

Observație: calculele de hash pentru frunze și noduri diferă; această separare de domeniu este necesară pentru rezistența la preimagine de ordinul doi (second preimage resistance).

Nu se cere ca lungimea listei de intrare să fie o putere a lui 2. Arborele rezultat poate fi dezechilibrat; forma sa este însă determinată unic de numărul de frunze. (Arborele este practic identic cu history tree-ul propus de [CrosbyWallach], cu excepția modului în care definiția noastră tratează arborii necompleți.)

2.1.2. Verificarea unui cap de arbore pornind de la înregistrări

Când un client are lista completă a înregistrărilor de la 0 până la tree_size - 1 și vrea să o verifice față de un root_hash returnat de jurnal pentru aceeași tree_size, poate fi folosit următorul algoritm:

1.  Se inițializează stiva ca fiind goală.

2.  Pentru fiecare i de la 0 până la tree_size - 1:
    a.  Se împinge HASH(0x00 || entries[i]) în stivă.
    b.  Se setează merge_count la cea mai mică valoare (inclusiv 0) pentru care
        LSB(i >> merge_count) nu este setat, unde LSB înseamnă bitul cel mai
        puțin semnificativ. Altfel spus, merge_count = numărul de 1 consecutivi
        începând de la bitul cel mai puțin semnificativ al lui i.
    c.  Se repetă merge_count ori:
        i.    Se scoate dreapta din stivă.
        ii.   Se scoate stânga din stivă.
        iii.  Se împinge HASH(0x01 || left || right) în stivă.

3.  Dacă stiva are mai mult de un element, se repetă aceeași procedură de
    îmbinare (sub-punctele 2(c)) până când rămâne un singur element.

4.  Elementul rămas în stivă este Merkle Tree Hash pentru tree_size dat și
    trebuie comparat prin egalitate cu root_hash furnizat.

2.1.3. Dovezi Merkle de includere

O dovadă de includere Merkle pentru o frunză este lista cea mai scurtă de noduri suplimentare necesare pentru a calcula Merkle Tree Hash-ul arborelui. Fiecare nod este fie o frunză, fie este calculat din cele două noduri imediat sub el. La fiecare pas spre rădăcină, un nod din dovadă este combinat cu nodul calculat până atunci. Dacă rădăcina calculată din dovadă se potrivește cu rădăcina reală, dovada demonstrează că frunza există în arbore.

2.1.3.1. Generarea unei dovezi de includere

Fiind dată lista ordonată D_n = {d[0], ..., d[n-1]}, dovada de includere PATH(m, D_n) pentru intrarea d[m], 0 ≤ m < n, este definită astfel:

PATH(0, {d[0]}) = {}

Pentru n > 1, fie k cea mai mare putere a lui 2 mai mică decât n:
PATH(m, D_n) = PATH(m, D[0:k]) : MTH(D[k:n])   pentru m < k
PATH(m, D_n) = PATH(m - k, D[k:n]) : MTH(D[0:k]) pentru m ≥ k

2.1.3.2. Verificarea unei dovezi de includere

Când un client primește o dovadă de includere (de exemplu, într-un TransItem de tip inclusion_proof_v2) și vrea să verifice includerea unui hash de intrare pentru o tree_size și un root_hash date:

1.  Se compară leaf_index din inclusion_proof_v2 cu tree_size. Dacă
    leaf_index ≥ tree_size, verificarea eșuează.
2.  fn = leaf_index; sn = tree_size - 1.
3.  r = hash.
4.  Pentru fiecare valoare p din tabloul inclusion_path:
    a.  Dacă sn este 0, se oprește iterația și verificarea eșuează.
    b.  Dacă LSB(fn) este setat, sau dacă fn == sn:
        i.   r = HASH(0x01 || p || r).
        ii.  Dacă LSB(fn) nu este setat, se deplasează la dreapta atât fn,
             cât și sn, până când LSB(fn) este setat sau fn este 0.
        Altfel:
        i.  r = HASH(0x01 || r || p).
    c.  În final, se deplasează la dreapta atât fn, cât și sn, o singură dată.
5.  Se compară sn cu 0 și r cu root_hash. Dacă sn == 0 și r == root_hash,
    jurnalul a demonstrat includerea lui hash. Altfel, verificarea eșuează.

2.1.4. Dovezi Merkle de consistență

Dovezile de consistență demonstrează proprietatea append-only a arborelui. O dovadă de consistență pentru MTH(D_n) și un hash anterior anunțat MTH(D[0:m]) al primelor m frunze, m ≤ n, este lista de noduri necesare pentru a verifica că primele m intrări D[0:m] sunt identice în ambii arbori. Dovada trebuie să conțină un set de noduri intermediare suficiente pentru a verifica MTH(D_n), astfel încât (un sub-set al) acelorași noduri să poată verifica și MTH(D[0:m]). Se definește un algoritm care produce dovada de consistență minimală (unică).

2.1.4.1. Generarea unei dovezi de consistență

PROOF(m, D_n) = SUBPROOF(m, D_n, true)

SUBPROOF(m, D_m, true)  = {}                       (subarbore complet cunoscut)
SUBPROOF(m, D_m, false) = {MTH(D_m)}               (altfel, pentru m = n)

Pentru m < n, fie k cea mai mare putere a lui 2 mai mică decât n:
  dacă m ≤ k:  SUBPROOF(m, D_n, b) = SUBPROOF(m, D[0:k], b) : MTH(D[k:n])
  dacă m > k:  SUBPROOF(m, D_n, b) = SUBPROOF(m - k, D[k:n], false) : MTH(D[0:k])

Numărul de noduri din dovada rezultată este mărginit superior de ceil(log2(n)) + 1.

2.1.4.2. Verificarea consistenței între două capete de arbore

Când un client are un cap de arbore first_hash pentru tree size first și un cap second_hash pentru tree size second, cu 0 < first < second, și a primit o dovadă de consistență între ele (de exemplu, într-un TransItem de tip consistency_proof_v2):

1.  Dacă consistency_path este un tablou gol, se oprește și verificarea eșuează.
2.  Dacă first este o putere exactă a lui 2, se adaugă first_hash la începutul
    tabloului consistency_path.
3.  fn = first - 1; sn = second - 1.
4.  Dacă LSB(fn) este setat, se deplasează la dreapta atât fn, cât și sn,
    până când LSB(fn) nu mai este setat.
5.  fr = sr = prima valoare din consistency_path.
6.  Pentru fiecare valoare ulterioară c din consistency_path:
    a.  Dacă sn este 0, se oprește iterația și verificarea eșuează.
    b.  Dacă LSB(fn) este setat sau fn == sn:
        i.    fr = HASH(0x01 || c || fr).
        ii.   sr = HASH(0x01 || c || sr).
        iii.  Dacă LSB(fn) nu este setat, se deplasează la dreapta atât fn,
              cât și sn, până când LSB(fn) este setat sau fn este 0.
        Altfel:
        i.  sr = HASH(0x01 || sr || c).
    c.  În final, se deplasează la dreapta atât fn, cât și sn, o singură dată.
7.  După parcurgerea tabloului, se verifică: fr == first_hash, sr == second_hash
    și sn == 0.

2.1.5. Exemplu

Următorul este un arbore Merkle binar cu 7 frunze:

              hash
             /    \
            k      l
           / \    / \
          g   h  i   j
         / \ / \ / \  |
         a b c d e f  d6
         | | | | | |
        d0 d1 d2 d3 d4 d5

Dovada de includere pentru d0: [b, h, l]
Dovada de includere pentru d3: [c, g, l]
Dovada de includere pentru d4: [f, j, k]
Dovada de includere pentru d6: [i, k]

Același arbore, construit incremental în patru pași: hash0 (cu d0..d2), apoi hash1=k (d0..d3), apoi hash2 (d0..d5), apoi hash (d0..d6).

hash0 = MTH(D[3])    hash1 = MTH(D[4])    hash2 = MTH(D[6])    hash = MTH(D[7])

Dovada de consistență între hash0 și hash: PROOF(3, D[7]) = [c, d, g, l].
  Nodurile c, g verifică hash0; nodurile d, l arată că hash este consistent cu hash0.
Dovada de consistență între hash1 și hash: PROOF(4, D[7]) = [l].
  hash poate fi verificat folosind hash1 = k și l.
Dovada de consistență între hash2 și hash: PROOF(6, D[7]) = [i, j, k].
  Nodurile k, i verifică hash2; nodul j arată că hash este consistent cu hash2.

2.2. Semnături

La semnarea structurilor de date, un jurnal trebuie să folosească unul dintre algoritmii de semnătură din registrul IANA „Signature Algorithms”, descris în Secțiunea 10.2.2.

05

Expeditori (submitters)

Expeditorii trimit jurnalelor certificate sau pre-anunțuri de certificate (precertificate), înainte de emitere, pentru auditare publică. Pentru a permite atribuirea fiecărui certificat sau precertificat înregistrat emitentului său, fiecare trimitere trebuie să fie însoțită de toate certificatele suplimentare necesare verificării lanțului până la o ancoră de încredere acceptată (Secțiunea 5.7). Ancorele de încredere (un certificat CA rădăcină sau intermediar) pot fi omise din trimitere.

Dacă jurnalul acceptă trimiterea, returnează o marcă temporală semnată (SCT, vezi Secțiunea 4.8). Expeditorul ar trebui să valideze SCT-ul returnat, conform Secțiunii 8.1, dacă îi înțelege formatul și intenționează să-l folosească direct într-un handshake TLS sau să construiască un certificat. Dacă expeditorul nu are nevoie de SCT (de exemplu, certificatul este trimis doar pentru a fi disponibil în jurnal), poate să-l valideze.

3.1. Certificate

Orice entitate poate trimite un certificat (Secțiunea 5.1) unui jurnal. Deoarece se anticipează că clienții TLS vor respinge certificatele neînregistrate, se așteaptă ca emitenții și subiecții certificatelor să fie puternic motivați să le trimită.

3.2. Precertificate

Autoritățile de certificare pot pre-anunța un certificat înainte de emitere, trimițând un precertificat (Secțiunea 5.1) pe care jurnalul îl poate folosi pentru a crea o înregistrare validă față de certificatul emis. CA poate încorpora SCT-ul returnat în certificatul emis. Un exemplu în care SCT-ul nu este încorporat: CA trimite precertificatul la mai multe jurnale, dar încorporează doar SCT-urile care se întorc primele.

Un precertificat este un obiect CMS [RFC5652] de tip signed-data care respectă următorul profil:

SignerInfo.signedAttrs este inclus în procesul de calcul al digestului mesajului (vezi Secțiunea 5.4 din [RFC5652]), ceea ce asigură că valoarea SignerInfo.signature nu va fi o semnătură X.509v3 validă care ar putea fi folosită împreună cu TBSCertificate (din SignedData.encapContentInfo.eContent) pentru a construi un certificat valid.

3.2.1. Legarea intenției de emitere

În condiții normale, există o scurtă întârziere între trimiterea precertificatului și emiterea certificatului corespunzător. Întârzieri mai lungi pot apărea ocazional (de exemplu, din cauza indisponibilității serverului de jurnal); în unele cazuri, CA s-ar putea să nu emită deloc certificatul. Cu toate acestea, semnătura unui precertificat indică intenția fermă (binding intent) a CA de a emite certificatul corespunzător, ceea ce înseamnă că:

06

Formatul și funcționarea jurnalului

Un jurnal este un singur arbore Merkle append-only de înregistrări de certificate și precertificate trimise.

Când primește și acceptă o trimitere validă, jurnalul trebuie să returneze un SCT corespunzător certificatului sau precertificatului trimis. Dacă jurnalul a mai văzut această trimitere validă, ar trebui să returneze același SCT ca înainte (discutat în Secțiunea 11.3). Dacă se produc SCT-uri diferite pentru aceeași trimitere, vor trebui create mai multe înregistrări, câte una pentru fiecare SCT (marca temporală face parte din structura frunzei). Dacă un certificat a fost înregistrat anterior ca precertificat, SCT-ul precertificatului (precert_sct_v2) nu este adecvat; trebuie generat un SCT nou de tip x509_sct_v2.

Un SCT este promisiunea jurnalului de a adăuga în arborele Merkle o înregistrare pentru trimiterea acceptată. După producerea SCT-ului, jurnalul trebuie să-și îndeplinească promisiunea în intervalul de timp numit Maximum Merge Delay (MMD), unul dintre parametrii jurnalului (Secțiunea 4.1), efectuând:

Jurnalul poate adăuga mai multe înregistrări înainte de a semna rădăcina. Operatorii de jurnal nu ar trebui să impună condiții pentru regăsirea sau partajarea datelor din jurnal.

4.1. Parametrii jurnalului

Un jurnal este definit de o colecție de parametri imutabili, folosiți de clienți pentru comunicare și verificarea artefactelor. Cu excepția STH-ului final, fiecare parametru trebuie stabilit înainte ca operatorul să înceapă operarea jurnalului.

ParametruDescriere
Base URLPrefixul folosit pentru a construi URL-urile [RFC3986] ale mesajelor client (Secțiunea 5). Trebuie să fie un URL „https”, poate conține port și o cale cu oricâte segmente, dar nu trebuie să conțină query string, fragment sau „/” final. Exemplu: https://ct.example.org/blue.
Hash AlgorithmAlgoritmul de hash folosit pentru arborele Merkle (Secțiunea 10.2.1).
Signature AlgorithmAlgoritmul de semnătură folosit (Secțiunea 2.2).
Public KeyCheia publică folosită pentru verificarea semnăturilor jurnalului. Un jurnal nu trebuie să folosească aceeași pereche de chei ca orice alt jurnal.
Log IDOID-ul care identifică unic jurnalul.
Maximum Merge DelayMMD-ul asumat de jurnal. Documentul nu impune deliberat limite de valoare, pentru a permite experimentarea.
VersionVersiunea protocolului suportată de jurnal (în prezent 1 sau 2).
Maximum Chain LengthCea mai lungă trimitere de lanț acceptată, dacă jurnalul impune o limită.
STH Frequency CountNumărul maxim de STH-uri pe care jurnalul le poate produce într-o perioadă egală cu MMD (Secțiunea 4.10).
Final STHDacă jurnalul a fost închis (nu mai acceptă intrări noi), înregistrările existente pot rămâne valide; clientul ar trebui să cunoască ultimul STH valid, ca TransItem signed_tree_head_v2, ca să nu poată fi adăugate intrări noi fără detectare. Dacă jurnalul încă acceptă intrări, această valoare nu ar trebui furnizată.

[JSON.Metadata] este un exemplu de format de metadate care include elementele de mai sus.

4.2. Evaluarea trimiterilor

Jurnalul decide dacă acceptă sau respinge o trimitere evaluând-o față de criteriile minime de acceptare (Secțiunea 4.2.1) și față de criteriile discreționare (Secțiunea 4.2.2). Dacă sunt îndeplinite, jurnalul ar trebui să accepte trimiterea (poate decide, de exemplu, să respingă temporar trimiteri acceptabile pentru a se proteja împotriva atacurilor DoS).

Jurnalul va permite regăsirea listei de ancore de încredere acceptate (Secțiunea 5.7), fiecare fiind un certificat CA rădăcină sau intermediar. Lista ar putea fi în mod util reuniunea certificatelor rădăcină acceptate de marii producători de browsere.

4.2.1. Criterii minime de acceptare

Pentru ca certificatele și precertificatele înregistrate să fie atribuibile unei ancore acceptate, pentru a seta așteptări clare monitorilor și pentru a nu fi copleșit de trimiteri invalide, jurnalul trebuie să respingă o trimitere dacă nu sunt îndeplinite condițiile:

4.2.2. Criterii discreționare de acceptare

Dacă criteriile minime sunt îndeplinite, dar trimiterea nu este complet validă conform regulilor de verificare [RFC5280] (de exemplu, certificatul a expirat, nu este încă valid, a fost revocat, prezintă erori de codificare DER dar jurnalul îl poate parsa etc.), acceptabilitatea rămâne la discreția jurnalului. Este util ca jurnalele să accepte astfel de trimiteri pentru a acomoda particularitățile software-ului de emitere și pentru a facilita monitorizarea conformității CA. Totuși, este impracticabil ca documentul să enumere toate modurile în care o trimitere ar putea să nu respecte [RFC5280].

Jurnalele ar trebui să limiteze lungimea lanțului acceptat; lungimea maximă este un parametru al jurnalului (Secțiunea 4.1).

4.3. Înregistrările jurnalului

Dacă o trimitere este acceptată și se emite un SCT, jurnalul trebuie să stocheze întregul lanț folosit la verificare: certificatul sau precertificatul însuși, certificatele intermediare furnizate și ancora de încredere folosită (chiar dacă a fost omisă din trimitere). Jurnalul trebuie să furnizeze acest lanț la cerere pentru audit (Secțiunea 5.6), ca CA să nu poată evita răspunderea înregistrând un lanț parțial sau gol. Fiecare înregistrare este o structură TransItem de tip x509_entry_v2 sau precert_entry_v2; jurnalul poate stoca însă în orice format. Dacă nu stochează TransItem-ul integral, trebuie să stocheze timestamp și sct_extensions din structura TimestampedCertificateEntryDataV2 corespunzătoare; TransItem-ul poate fi reconstruit din aceste câmpuri și din lanțul complet.

4.4. ID-ul jurnalului

Fiecare jurnal este identificat printr-un OID, unul dintre parametrii jurnalului, care nu trebuie folosit pentru niciun alt jurnal. Operatorul trebuie să aloce OID-ul singur sau să ceară unul din registrul Log ID (Secțiunea 10.2.5). O modalitate de a obține un arc OID este solicitarea unui Private Enterprise Number de la IANA. Singurul avantaj al registrului este că o codificare DER poate fi mică. (Alocările OID nu necesită înregistrare centrală, deși jurnalele vor dori probabil să se facă cunoscute clienților prin mijloace out-of-band.) Diverse structuri includ codificarea DER a OID-ului, fără tag-ul ASN.1 și fără octeții de lungime, într-un vector opac:

opaque LogID<2..127>;

Lungimea ASN.1 și lungimea vectorului opac sunt identice ca dimensiune (1 octet) și valoare, deci codificarea DER completă (inclusiv tag și lungime) poate fi reprodusă simplu, adăugând tag-ul OBJECT IDENTIFIER (0x06) la început. OID-ul folosit este limitat astfel încât codificarea DER a valorii, fără tag și lungime, trebuie să aibă cel mult 127 de octeți.

4.5. Structura TransItem

Diverse structuri de date sunt încapsulate în TransItem pentru ca tipul și versiunea fiecăreia să fie identificate într-un mod comun:

enum {
    x509_entry_v2(0x0100), precert_entry_v2(0x0101),
    x509_sct_v2(0x0102), precert_sct_v2(0x0103),
    signed_tree_head_v2(0x0104), consistency_proof_v2(0x0105),
    inclusion_proof_v2(0x0106),
    reserved_rfc6962(0x0000..0x00FF),
    reserved_experimentaluse(0xE000..0xEFFF),
    reserved_privateuse(0xF000..0xFFFF),
    (0xFFFF)
} VersionedTransType;

struct {
    VersionedTransType versioned_type;
    select (versioned_type) {
        case x509_entry_v2: TimestampedCertificateEntryDataV2;
        case precert_entry_v2: TimestampedCertificateEntryDataV2;
        case x509_sct_v2: SignedCertificateTimestampDataV2;
        case precert_sct_v2: SignedCertificateTimestampDataV2;
        case signed_tree_head_v2: SignedTreeHeadDataV2;
        case consistency_proof_v2: ConsistencyProofDataV2;
        case inclusion_proof_v2: InclusionProofDataV2;
    } data;
} TransItem;

versioned_type este o valoare din registrul IANA din Secțiunea 10.2.3 care identifică tipul structurii încapsulate și cea mai veche versiune a protocolului căreia i se conformează. Acest document este v2. data este structura încapsulată; structurile cu sufixul DataV2 sunt definite în secțiunile următoare.

VersionedTransType combină enumerările v1 Version, LogEntryType, SignatureType și MerkleLeafType [RFC6962]. v1 nu definea TransItem, dar acest document oferă orientări (Anexa A) pentru coexistența implementărilor v2 cu cele v1.

Versiunile viitoare pot reutiliza valorile VersionedTransType definite aici atâta timp cât structurile nu sunt modificate și pot adăuga valori noi pentru structuri noi sau modificate.

4.6. Extensiile de artefacte de jurnal

enum {
    reserved(65535)
} ExtensionType;

struct {
    ExtensionType extension_type;
    opaque extension_data<0..2^16-1>;
} Extension;

Structura Extension oferă extensibilitate generică pentru artefactele jurnalului, inclusiv SCT (Secțiunea 4.8) și STH (Secțiunea 4.10). Interpretarea câmpului extension_data este determinată doar de extension_type. Documentul nu definește extensii, dar stabilește un registru pentru valorile viitoare (Secțiunea 10.2.4). Fiecare document care înregistrează o extensie nouă trebuie să specifice contextul de utilizare (SCT, STH sau ambele) și interpretarea extension_data.

4.7. Frunzele arborelui Merkle

Frunzele corespund înregistrărilor jurnalului (Secțiunea 4.3). Fiecare frunză este hash-ul de frunză (Secțiunea 2.1) al unei structuri TransItem de tip x509_entry_v2 sau precert_entry_v2, care încapsulează TimestampedCertificateEntryDataV2. Hash-urile de frunză se calculează ca HASH(0x00 || TransItem), algoritmul fiind un parametru al jurnalului.

opaque TBSCertificate<1..2^24-1>;

struct {
    uint64 timestamp;
    opaque issuer_key_hash<32..2^8-1>;
    TBSCertificate tbs_certificate;
    Extension sct_extensions<0..2^16-1>;
} TimestampedCertificateEntryDataV2;

timestamp este data și ora acceptării certificatului sau precertificatului: un număr nesemnat de 64 de biți, în miimi de secundă de la Unix Epoch (1 ianuarie 1970, 00:00:00 UTC), ignorând secundele bisecte, în ordine de rețea. Frunzele nu trebuie să fie în ordine cronologică strictă.

issuer_key_hash este HASH al cheii publice a CA emitente, calculat peste codificarea DER a cheii reprezentate ca SubjectPublicKeyInfo [RFC5280]. Leagă CA de certificat/precertificat, făcând imposibil ca SCT-ul corespunzător să fie valid pentru orice alt certificat al cărui TBSCertificate coincide cu tbs_certificate. Lungimea trebuie să corespundă cu HASH_SIZE.

tbs_certificate este TBSCertificate codificat DER din trimitere (TBSCertificate-ul unui precertificat poate fi reconstruit din certificatul corespunzător, Secțiunea 8.1.2). sct_extensions este identic, octet cu octet, cu extensiile SCT ale SCT-ului corespunzător. Tipul TransItem corespunde valorii parametrului type din apelul Secțiunii 5.1.

4.8. Signed Certificate Timestamp (SCT)

Un SCT este o structură TransItem de tip x509_sct_v2 sau precert_sct_v2, care încapsulează SignedCertificateTimestampDataV2:

struct {
    LogID log_id;
    uint64 timestamp;
    Extension sct_extensions<0..2^16-1>;
    opaque signature<1..2^16-1>;
} SignedCertificateTimestampDataV2;

log_id este ID-ul unic al jurnalului (Secțiunea 4.4). timestamp este egal cu timestamp din TimestampedCertificateEntryDataV2 corespunzătoare.

sct_extensions este un vector de zero sau mai multe extensii SCT. Nu trebuie să includă mai mult de o extensie cu același extension_type și trebuie ordonat după valoarea extension_type, crescător. Extensiile SCT sunt similare extensiilor X.509v3 necritice (mustUnderstand nu este setat); un destinatar ar trebui să ignore orice extensie neînțeleasă și poate alege să ignore extensii pe care le înțelege.

signature este calculată peste o structură TransItem de tip x509_entry_v2 sau precert_entry_v2 (Secțiunea 4.7), folosind algoritmul de semnătură declarat în parametrii jurnalului.

4.9. Capul arborelui Merkle (Tree Head)

opaque NodeHash<32..2^8-1>;

struct {
    uint64 timestamp;
    uint64 tree_size;
    NodeHash root_hash;
    Extension sth_extensions<0..2^16-1>;
} TreeHeadDataV2;

Lungimea NodeHash trebuie să corespundă cu HASH_SIZE a jurnalului. timestamp este data și ora curentă (formatul din Secțiunea 4.7); tree_size este numărul de înregistrări din arbore; root_hash este rădăcina arborelui; sth_extensions este un vector de extensii STH, cu aceleași reguli de unicitate și ordonare ca la SCT; extensiile neînțelese ar trebui ignorate.

4.10. Signed Tree Head (STH)

Periodic, fiecare jurnal ar trebui să semneze informațiile curente ale capului de arbore pentru a produce un STH. La cererea celui mai recent STH (Secțiunea 5.2), jurnalul trebuie să returneze un STH nu mai vechi decât MMD. Deoarece STH-urile ar putea fi folosite pentru marcarea clienților (producând un STH nou la fiecare interogare), jurnalul nu trebuie să producă STH-uri mai des decât declară parametrii. În general, nu e nevoie de un STH nou dacă nu există înregistrări noi; dacă jurnalul nu acceptă nicio trimitere într-o perioadă MMD, trebuie să semneze același Merkle Tree Hash cu o marcă temporală proaspătă.

struct {
    LogID log_id;
    TreeHeadDataV2 tree_head;
    opaque signature<1..2^16-1>;
} SignedTreeHeadDataV2;

timestamp din tree_head trebuie să fie cel puțin la fel de recent ca cel mai recent timestamp SCT din arbore, iar fiecare timestamp ulterior trebuie să fie mai recent decât cel anterior. signature este calculată peste câmpul tree_head.

4.11. Dovezi Merkle de consistență

struct {
    LogID log_id;
    uint64 tree_size_1;
    uint64 tree_size_2;
    NodeHash consistency_path<0..2^16-1>;
} ConsistencyProofDataV2;

tree_size_1 este dimensiunea arborelui mai vechi, tree_size_2 a celui mai nou; consistency_path este un vector de noduri care demonstrează consistența a două STH-uri (Secțiunea 2.1.4).

4.12. Dovezi Merkle de includere

struct {
    LogID log_id;
    uint64 tree_size;
    uint64 leaf_index;
    NodeHash inclusion_path<0..2^16-1>;
} InclusionProofDataV2;

tree_size este dimensiunea arborelui pe care se bazează dovada; leaf_index este indexul (de la 0) al înregistrării; inclusion_path este vectorul de noduri care demonstrează includerea (Secțiunea 2.1.3).

4.13. Închiderea unui jurnal

Operatorii pot închide un jurnal din diverse motive (de exemplu, deprecierea algoritmului de semnătură). Dacă există înregistrări pentru certificate neexpirate, simpla oprire a recunoașterii jurnalului de către clienți ar invalida SCT-urile. Pentru a evita acest lucru, ar trebui luate următoarele măsuri:

07

Mesajele clientului către jurnal

Mesajele sunt cereri HTTPS GET sau POST. Parametrii pentru POST și toate răspunsurile sunt obiecte JSON [RFC8259]. Parametrii pentru GET sunt parametri URL cheie/valoare independenți de ordine, în format „application/x-www-form-urlencoded” [HTML401]. Datele binare sunt codificate base64 conform Secțiunii 4 din [RFC4648].

Clienții sunt configurați cu base URL-ul jurnalului; construiesc URL-urile adăugând sufixe la acest prefix. Structura restricționează într-o oarecare măsură modul de implementare (vezi [RFC8820]), dar experiența cu v1 nu a indicat probleme practice.

Obiectele JSON și parametrii URL pot conține câmpuri nespecificate, pentru experimentare; câmpurile neînțelese ar trebui ignorate.

În practică, un jurnal poate avea mai multe front-end-uri. Deoarece nu pot fi păstrate perfect sincronizate, pot apărea erori cauzate de decalaj. Front-end-urile trebuie să servească doar date fără goluri (de exemplu, niciun front-end nu răspunde cu un STH dacă nu poate dovedi și consistența din toate înregistrările incluse în acel STH).

De exemplu, când se cere o dovadă de consistență între două STH-uri, front-end-ul atins poate să nu cunoască unul sau ambele. Dacă nu cunoaște niciunul, returnează cel mai recent STH cunoscut. Dacă îl cunoaște pe primul dar nu pe al doilea, returnează STH-ul cel mai recent cunoscut și o dovadă de consistență de la primul STH la cel returnat. Cazul în care îl cunoaște pe al doilea dar nu pe primul nu ar trebui să apară (cerința „fără goluri”).

Dacă jurnalul nu poate procesa o cerere, trebuie să returneze un cod HTTP 4xx/5xx [RFC7231], iar corpul ar trebui să fie un obiect JSON problem details [RFC7807] care conține:

Exemplu (400 Bad Request la get-entries?start=100&end=99):
{
    "type": "urn:ietf:params:trans:error:endBeforeStart",
    "detail": "'start' cannot be greater than 'end'"
}

Majoritatea tipurilor de eroare sunt specifice cererii; excepția este „malformed”, care indică faptul că serverul nu a putut parsa cererea pentru că nu respecta documentul:

typedetail
malformedThe request could not be parsed. (Cererea nu a putut fi parsata.)

Clienții ar trebui să trateze 500 și 503 drept eșecuri tranzitorii și pot reîncerca aceeași cerere mai târziu. La 503, jurnalul poate include header-ul Retry-After [RFC7231]. Clienții ar trebui să trateze orice eroare 4xx ca pe o problemă a cererii și să nu o reînainteze nemodificată.

5.1. Trimiterea unei înregistrări la jurnal

POST <Base URL>/ct/v2/submit-entry

Intrări:

Ieșiri: sct — un TransItem x509_sct_v2 sau precert_sct_v2 semnat de jurnal. Dacă înregistrarea este adăugată imediat (sau există deja), jurnalul ar trebui să producă și sth (signed_tree_head_v2 semnat) și inclusion (inclusion_proof_v2 care demonstrează includerea în STH-ul returnat).

typedetail (tradus)
badSubmissionTrimiterea nu este nici certificat, nici precertificat valid.
badTypetype nu este nici 1, nici 2.
badChainPrimul element din chain nu certifică trimiterea, sau al doilea nu îl certifică pe primul etc.
badCertificateUnul sau mai multe certificate din chain nu sunt valide (ex.: codificate incorect).
unknownAnchorUltimul element din chain (sau trimiterea, dacă chain e gol) nu este, și nu este certificat de, o ancoră de încredere acceptată.
shutdownJurnalul nu mai acceptă trimiteri.

Dacă versiunea sct nu este v2, clientul v2 poate să nu poată verifica semnătura; nu trebuie să considere acest lucru o eroare, pentru a nu forța actualizarea clienților v2 care nu folosesc SCT-urile returnate.

Dacă jurnalul detectează codificare proastă într-un lanț care altfel verifică, trebuie fie să înregistreze certificatul (și să emită SCT), fie să returneze eroarea „badCertificate”. Înregistrarea este utilă pentru că monitorii (Secțiunea 8.2) pot detecta erorile de codificare, care pot fi acceptate de unii clienți TLS.

Dacă trimiterea este o ancoră de încredere acceptată al cărei certificator nu este nici ancoră acceptată, nici primul element din chain, jurnalul trebuie să returneze „unknownAnchor”; nu poate genera un SCT fără cheia publică a emitentului.

Dacă SCT-ul returnat este destinat clienților TLS, atunci sth și inclusion (dacă sunt returnate) ar trebui furnizate și ele clienților TLS. De exemplu, dacă type a fost 2, toate cele trei TransItem-uri ar putea fi încorporate în certificat.

5.2. Regăsirea celui mai recent STH

GET <Base URL>/ct/v2/get-sth — fără intrări. Ieșire: sth — un TransItem signed_tree_head_v2 semnat, nu mai vechi decât MMD.

5.3. Dovada de consistență între două STH-uri

GET <Base URL>/ct/v2/get-sth-consistency — intrări: first (tree_size al arborelui mai vechi, zecimal) și second (opțional). Ambele dimensiuni trebuie să provină din STH-uri v2 existente. Din cauza decalajului, front-end-ul poate cunoaște unul, ambele sau niciunul; răspunsurile sunt adaptate (vezi textul original, Secțiunea 5.3). Ieșiri: consistency (consistency_proof_v2; dacă first == second, dovada trebuie să fie goală) și sth. Nu se cere semnătură pentru consistency, pentru că verifică consistența între STH-uri deja semnate.

typedetail (tradus)
firstUnknownfirst este înaintea celui mai recent STH cunoscut, dar nu provine dintr-un STH existent.
secondUnknownsecond este înaintea celui mai recent STH cunoscut, dar nu provine dintr-un STH existent.
secondBeforeFirstsecond este mai mic decât first.

5.4. Dovada de includere după hash-ul frunzei

GET <Base URL>/ct/v2/get-proof-by-hash — intrări: hash (hash de frunză v2 base64) și tree_size (zecimal). Hash-ul trebuie calculat conform Secțiunii 4.7 și trebuie să existe un STH v2 pentru tree_size. Din cauza decalajului, front-end-ul poate returna STH-ul cel mai recent cunoscut cu o dovadă de includere față de el. Ieșiri: inclusion și sth; nu se cere semnătură pentru inclusion.

typedetail (tradus)
hashUnknownhash nu este hash-ul unei frunze cunoscute (posibil din cauza decalajului sau a unui certificat cunoscut, dar neîmbinat încă).
treeSizeUnknownhash este înaintea celui mai recent STH cunoscut, dar nu provine dintr-un STH existent.

5.5. Dovada de includere, STH și dovada de consistență după hash-ul frunzei

GET <Base URL>/ct/v2/get-all-by-hash — intrări: hash și tree_size. Din cauza decalajului apar mai multe cazuri:

CazRăspuns
cel mai recent STH < capul de arbore cerutSe returnează cel mai recent STH.
cel mai recent STH > capul de arbore cerutSe returnează STH-ul și o dovadă de consistență între el și capul cerut (Secțiunea 5.3).
indexul hash-ului cerut < cel mai recent STHSe returnează inclusion.

Pot fi adevărate mai multe cazuri; atunci se returnează reuniunea datelor. Dacă niciunul nu e adevărat, front-end-ul trebuie să returneze un răspuns gol. Ieșiri: inclusion, sth, consistency. Erorile sunt aceleași ca la Secțiunea 5.4.

5.6. Regăsirea înregistrărilor și a STH-ului

GET <Base URL>/ct/v2/get-entries — intrări: start și end (indexuri zecimale). Ieșiri: entries — un tablou de obiecte, fiecare cu:

Mesajul nu este semnat; datele pot fi verificate construind Merkle Tree Hash-ul corespunzător unui STH regăsit. Toate frunzele trebuie să fie v2, dar un client v2 conform nu trebuie să considere un tip TransItem nerecunoscut o eroare: poate să nu parseze unele înregistrări, dar poate verifica integritatea tratând frunzele necunoscute ca intrare opacă.

start și end ar trebui să fie în intervalul 0 ≤ x < tree_size; start trebuie să fie ≤ end. Fiecare submitted_entry trebuie să includă ancora de încredere folosită la verificare, chiar dacă nu a fost furnizată la submit-entry; dacă trimiterea nu se auto-certifică, primul element din chain trebuie să fie prezent și să o certifice.

Serverele trebuie să onoreze cererile cu end ≥ tree_size returnând un răspuns parțial. Jurnalele pot limita numărul de înregistrări per cerere; dacă se cere mai mult, vor returna maximul permis, secvențial, începând cu start (limita nu este imutabilă și nu apare în parametrii din Secțiunea 4.1). Dacă nu există înregistrări între start și end (decalaj), se returnează un tablou entries gol. În orice caz, se returnează cel mai recent STH cunoscut.

typedetail (tradus)
startUnknownstart este mai mare decât numărul de înregistrări din arbore.
endBeforeStartstart nu poate fi mai mare decât end.

5.7. Regăsirea ancorelor de încredere acceptate

GET <Base URL>/ct/v2/get-anchors — fără intrări. Ieșiri: certificates (un tablou de certificate CA acceptabile, base64) și max_chain_length (opțional; lungimea maximă a lanțului, zecimal). Datele nu sunt semnate; protocolul se bazează pe garanțiile de securitate ale TLS.

08

Servere TLS

Serverele TLS care folosesc CT trebuie să folosească cel puțin unul dintre mecanismele descrise mai jos pentru a prezenta fiecărui client TLS, la handshake-uri complete, la cererea clientului, unul sau mai multe SCT-uri de la unul sau mai multe jurnale, fiecare SCT corespunzând certificatului serverului. (Un server poate trimite o extensie TLS doar dacă clientul a specificat-o mai întâi.) Serverele ar trebui să prezinte și dovezile de includere și STH-urile corespunzătoare.

6.1. Autentificarea clienților TLS

Această specificație nu descrie cum poate un server TLS folosi CT pentru certificatele de client TLS. Deși util, nu este documentat aici deoarece: expunerea mai mare de securitate este ca un client să interacționeze cu un server ilegitim; iar certificatele de client TLS nu sunt, în general, de așteptat să fie trimise la jurnale CT. O versiune viitoare ar putea include astfel de informații.

6.2. SCT-uri multiple

Serverele TLS care folosesc CT ar trebui să trimită SCT-uri de la mai multe jurnale, deoarece:

Pentru selectarea jurnalelor, un server TLS poate examina setul de jurnale acceptate de clienții TLS populari.

6.3. Structura TransItemList

opaque SerializedTransItem<1..2^16-1>;

struct {
    SerializedTransItem trans_item_list<1..2^16-1>;
} TransItemList;

SerializedTransItem este un șir de octeți opac ce conține structura TransItem serializată. Această codificare asigură că clienții TLS pot decoda fiecare TransItem individual (de exemplu, la o actualizare de versiune, clienții vechi pot parsa structurile vechi și sări peste cele noi).

6.4. Prezentarea SCT-urilor, dovezilor de includere și STH-urilor

În fiecare TransItemList trimis în timpul unui handshake TLS, serverul trebuie să includă un TransItem de tip x509_sct_v2 sau precert_sct_v2. Prezentarea dovezilor de includere și a STH-urilor protejează confidențialitatea clientului (Secțiunea 8.1.4) și reduce încărcarea jurnalelor; prin urmare, dacă serverul le poate obține, ar trebui să le includă și pe acestea.

6.5. Extensia TLS transparency_info

Dacă un client TLS include tipul de extensie transparency_info în ClientHello și serverul o suportă:

Serverele TLS trebuie să includă această extensie doar în: mesajul ServerHello (TLS 1.2 sau mai vechi) sau mesajul Certificate/CertificateRequest (TLS 1.3). Serverele nu trebuie să proceseze sau să includă extensia la reluarea sesiunii TLS, deoarece reluarea folosește informațiile sesiunii originale.

09

Autorități de certificare

7.1. Extensia X.509v3 Transparency Information

Extensia Transparency Information X.509v3, cu OID 1.3.101.75 și care ar trebui să fie necritică, conține una sau mai multe structuri TransItem într-un TransItemList. Poate fi inclusă în răspunsuri OCSP (7.1.1) și în certificate (7.1.2). Deoarece [RFC5280] cere ca extnValue (un OCTET STRING) să conțină codificarea DER a unei valori ASN.1, un TransItemList nu trebuie inclus direct; trebuie înfășurat într-un OCTET STRING suplimentar:

TransparencyInformationSyntax ::= OCTET STRING

TransparencyInformationSyntax conține un TransItemList.

7.1.1. Extensie în răspunsul OCSP

O CA poate include extensia Transparency Information în singleExtensions ale unui SingleResponse dintr-un răspuns OCSP. Toate SCT-urile și dovezile de includere incluse trebuie să fie pentru certificatul identificat de certID-ul acelui SingleResponse sau pentru un precertificat corespunzător acelui certificat.

7.1.2. Extensie în certificat

O CA poate include extensia Transparency Information într-un certificat. Toate SCT-urile și dovezile incluse trebuie să fie pentru un precertificat care corespunde acestui certificat.

7.2. Extensia X.509v3 TLS Feature

O CA nu ar trebui să emită certificate care identifică extensia TLS transparency_info într-o extensie TLS feature [RFC7633], deoarece serverele TLS nu sunt obligate să suporte extensia transparency_info pentru a participa la CT (Secțiunea 6).

10

Clienți

Există diverse funcții pe care clienții jurnalelor le pot îndeplini. Descriem aici câțiva clienți tipici și cum ar trebui să funcționeze. Orice inconsistență poate fi folosită ca dovadă că un jurnal nu s-a comportat corect, iar semnăturile de pe structurile de date împiedică jurnalul să nege comportamentul greșit.

Toți clienții au nevoie de diverși parametri pentru a comunica cu jurnalele și a verifica răspunsurile, descriși în Secțiunea 4.1.

8.1. Client TLS

8.1.1. Primirea SCT-urilor și a dovezilor de includere

Clienții TLS primesc SCT-uri și dovezi de includere odată cu certificatele sau separat. Clienții TLS care folosesc CT trebuie să implementeze toate cele trei mecanisme prin care serverele TLS pot prezenta SCT-uri (Secțiunea 6).

Clienții TLS care suportă extensia TLS transparency_info (Secțiunea 6.5) ar trebui să o includă în ClientHello, cu extension_data gol. Dacă un server TLS include extensia transparency_info la reluarea unei sesiuni TLS, clientul trebuie să abandoneze handshake-ul.

8.1.2. Reconstruirea TBSCertificate

Validarea unui SCT pentru un certificat (TransItem de tip x509_sct_v2) folosește componenta TBSCertificate nemodificată a certificatului.

Înainte de validarea unui SCT pentru un precertificat (precert_sct_v2), componenta TBSCertificate a precertificatului trebuie reconstruită din componenta TBSCertificate a certificatului astfel:

8.1.3. Validarea SCT-urilor

Pentru a folosi un SCT primit, clientul TLS trebuie mai întâi să-l valideze:

Dacă clientul nu are parametrii jurnalului corespunzător, nu poate valida SCT-ul. La evaluarea conformității (8.1.6), clientul va lua în considerare doar SCT-urile pe care a reușit să le valideze. Validarea SCT nu înlocuiește validarea normală a certificatului serverului și a lanțului său.

8.1.4. Obținerea dovezilor de includere

Când un client TLS a validat un SCT, dar nu are încă dovada de includere corespunzătoare, poate cere dovada direct de la jurnal, folosind get-proof-by-hash (5.4) sau get-all-by-hash (5.5).

Obținerea dovezilor direct de la jurnal dezvăluie jurnalului cu ce server TLS a comunicat clientul — o preocupare semnificativă de confidențialitate. De aceea, este de preferat ca serverul TLS să trimită dovezile (Secțiunea 6.4).

8.1.5. Validarea dovezilor de includere

Când un client TLS a primit (sau a obținut) o dovadă de includere și un STH, ar trebui să verifice dovada față de STH-ul furnizat. Clientul ar trebui să verifice și consistența între STH-ul furnizat și un STH pe care îl cunoaște.

Dacă clientul deține un STH anterior SCT-ului, poate, în procesul de audit, să ceară un STH nou (5.2) și să-l verifice cerând o dovadă de consistență (5.3). Dacă folosește get-all-by-hash, va avea deja STH-ul nou.

8.1.6. Evaluarea conformității

Politica locală a clientului specifică cantitatea și forma dovezilor (SCT-uri, dovezi de includere sau o combinație) necesare pentru conformitate și modul de tratare a neconformității.

Un client TLS poate evalua conformitatea doar dacă a dat serverului ocazia să trimită SCT-uri și dovezi prin oricare dintre cele trei mecanisme obligatorii (8.1.1). Prin urmare, nu trebuie să evalueze conformitatea dacă nu a inclus atât extensia transparency_info, cât și extensia status_request în ClientHello.

8.2. Monitor

Monitorii urmăresc jurnalele pentru a verifica un comportament corect, pentru certificate de interes sau pentru ambele. De exemplu, un monitor poate fi configurat să raporteze toate certificatele aplicate unui anumit nume de domeniu atunci când obține înregistrări noi pentru validarea consistenței.

Un monitor trebuie cel puțin să inspecteze fiecare înregistrare nouă din fiecare jurnal urmărit și poate păstra copii ale jurnalelor întregi.

Pentru a inspecta toate înregistrările existente, monitorul ar trebui să parcurgă acești pași o dată pentru fiecare jurnal:

  1. Obține STH-ul curent (5.2).
  2. Verifică semnătura STH-ului.
  3. Obține toate înregistrările din arborele corespunzător STH-ului (5.6).
  4. Dacă e cazul, verifică dacă fiecare înregistrare este un certificat de interes.
  5. Confirmă că arborele construit din înregistrări produce același hash ca în STH.

Pentru a inspecta înregistrări noi, monitorul ar trebui să repete următorii pași pentru fiecare jurnal:

  1. Obține STH-ul curent (5.2), repetând până când STH-ul se schimbă. Documentul nu specifică frecvența de polling, pentru a permite experimentarea.
  2. Verifică semnătura STH-ului.
  3. Obține toate înregistrările noi din arborele corespunzător (5.6). Dacă rămân indisponibile o perioadă lungă, aceasta ar trebui privită ca o comportare greșită a jurnalului.
  4. Dacă e cazul, verifică fiecare înregistrare pentru certificate de interes.
  5. Fie: (a) verifică că lista actualizată a tuturor înregistrărilor generează un arbore cu același hash ca noul STH; ori, dacă nu păstrează toate înregistrările: (a) obține o dovadă de consistență pentru noul STH cu STH-ul anterior (5.3), (b) verifică dovada, (c) verifică că noile înregistrări generează elementele corespunzătoare din dovadă.
  6. Se reia de la pasul 1.

8.3. Auditarea

Auditarea asigură că starea publicată curentă a unui jurnal este accesibilă din stările publicate anterior, cunoscute ca bune, și că promisiunile făcute de jurnal sub formă de SCT-uri au fost respectate. Auditurile sunt efectuate de monitori sau de clienți TLS.

În special, patru proprietăți ale comportamentului jurnalului ar trebui verificate: Maximum Merge Delay (MMD), STH Frequency Count, proprietatea append-only și consistența vederii jurnalului prezentată tuturor surselor de interogare.

Un jurnal benign și conform publică o serie de STH-uri în timp, fiecare derivat din STH-ul anterior și din înregistrările adăugate de la publicarea anterioară. Acest lucru poate fi dovedit prin auditarea STH-urilor. SCT-urile returnate clienților TLS pot fi auditate prin verificarea față de certificatul însoțitor și prin dovezi Merkle de includere.

Acțiunea auditorului în caz de eșec nu este specificată, dar, în general, dacă un audit eșuează, auditorul deține o dovadă semnată a comportamentului greșit al jurnalului.

Un monitor (8.2) poate audita verificând consistența STH-urilor primite, asigurându-se că fiecare înregistrare poate fi obținută și că STH-ul este într-adevăr rezultatul construirii unui arbore din toate înregistrările obținute.

Un client TLS (8.1) poate audita verificând un SCT față de orice STH datat după timestamp SCT + Maximum Merge Delay, cerând o dovadă Merkle de includere (5.4). Poate verifica și că SCT-ul corespunde certificatului serverului cu care a sosit (adică înregistrarea este acel certificat sau un precertificat corespunzător).

Verificarea consistenței vederii jurnalului prezentată tuturor entităților este mai dificilă, pentru că necesită o modalitate de partajare a răspunsurilor între entități; este discutată în Secțiunea 11.3.

11

Agilitate algoritmică

Nu este posibil ca un jurnal să își schimbe algoritmii pe parcursul vieții sale:

Permiterea mai multor algoritmi ar cere ca toate structurile de date să îi suporte și ar complica semnificativ implementarea clientului; de aceea nu este suportat de acest document.

Dacă devine necesară deprecierea unui algoritm folosit de un jurnal activ, jurnalul trebuie înghețat (Secțiunea 4.13), iar un jurnal nou ar trebui pornit. Certificatele din jurnalul înghețat care nu au expirat și necesită SCT-uri noi ar trebui trimise noului jurnal, iar SCT-urile de la acesta folosite în loc.

12

Considerații IANA

Criteriile de alocare menționate aici se referă la politicile din [RFC8126].

10.1. Adăugiri la registre existente

10.1.1. Intrarea nouă în registrul TLS ExtensionType

IANA a adăugat următoarea intrare în registrul „TLS ExtensionType Values” definit în [RFC8446]:

ValoareNume extensieTLS 1.3Doar DTLSRecomandatReferință
52transparency_infoCH, CR, CTNYRFC 9162

10.1.2. Sub-namespace-ul URN pentru TRANS (urn:ietf:params:trans)

IANA a adăugat o intrare nouă în registrul „IETF URN Sub-namespace for Registered Protocol Parameter Identifiers”, urmând șablonul din [RFC3553]:

10.2. Registre noi legate de CT

IANA a adăugat un registru de protocol nou, „Public Notary Transparency”, la lista de la https://www.iana.org/assignments/. Sub-registrele create sunt definite mai jos.

10.2.1. Algoritmi de hash

IntervalProceduri de înregistrare
0x00–0xDFSpecification Required
0xE0–0xEFExperimental Use
0xF0–0xFFPrivate Use
ValoareAlgoritmOIDReferință
0x00SHA-2562.16.840.1.101.3.4.2.1[RFC6234]
0x01–0xDFNealocatRFC 9162
0xE0–0xEFRezervat pentru Experimental UseRFC 9162
0xF0–0xFFRezervat pentru Private UseRFC 9162

Experții desemnați ar trebui să se asigure că algoritmul propus are o specificație publică și este adecvat ca algoritm criptografic de hash, fără atacuri cunoscute de preimagine sau coliziune (care pot deteriora integritatea jurnalului).

10.2.2. Algoritmi de semnătură

IANA a stabilit registrul „Signature Algorithms”, un sub-set al registrului „TLS SignatureScheme”, limitat la algoritmii adecvați pentru CT. Un avantaj major este folosirea expertizei TLS Working Group. Notă: valoarea 0x0403 apare de două ori; este acceptabil, deoarece procesul de verificare este același pentru ambii algoritmi, iar alegerea la generarea semnăturii este internă serverului de jurnal.

IntervalProceduri de înregistrare
0x0000–0x0807Specification Required
0x0808–0xFDFFExpert Review
0xFE00–0xFEFFExperimental Use
0xFF00–0xFFFFPrivate Use
Valoare SignatureSchemeAlgoritm de semnăturăReferință
0x0000–0x0402Nealocat
ecdsa_secp256r1_sha256 (0x0403)ECDSA (NIST P-256) cu SHA-256[FIPS186-4]
ecdsa_secp256r1_sha256 (0x0403)ECDSA determinist (NIST P-256) cu HMAC-SHA256[RFC6979]
0x0404–0x0806Nealocat
ed25519 (0x0807)Ed25519 (PureEdDSA cu curba edwards25519)[RFC8032]
0x0808–0xFDFFNealocat
0xFE00–0xFEFFRezervat pentru Experimental UseRFC 9162
0xFF00–0xFFFFRezervat pentru Private UseRFC 9162

Experții desemnați ar trebui să se asigure că algoritmul propus are specificație publică, are o valoare alocată în registrul „TLS SignatureScheme” și este adecvat ca algoritm de semnătură criptografic.

10.2.3. VersionedTransTypes

Registrul „VersionedTransTypes” are procedurile: 0x0100–0xDFFF Specification Required; 0xE000–0xEFFF Experimental Use; 0xF000–0xFFFF Private Use. Intervalul 0x0000..0x00FF este rezervat ca SCT-urile v1 să fie distinse de SCT-urile v2 și de alte structuri TransItem.

ValoareTip și versiuneReferință
0x0000–0x00FFRezervat[RFC6962]
0x0100x509_entry_v2RFC 9162
0x0101precert_entry_v2RFC 9162
0x0102x509_sct_v2RFC 9162
0x0103precert_sct_v2RFC 9162
0x0104signed_tree_head_v2RFC 9162
0x0105consistency_proof_v2RFC 9162
0x0106inclusion_proof_v2RFC 9162
0x0107–0xDFFFNealocat
0xE000–0xEFFFRezervat pentru Experimental UseRFC 9162
0xF000–0xFFFFRezervat pentru Private UseRFC 9162

10.2.4. Extensii de artefacte de jurnal

Registrul „Log Artifact Extensions” are procedurile: 0x0000–0xDFFF Specification Required; 0xE000–0xEFFF Experimental Use; 0xF000–0xFFFF Private Use. Coloana „Use” ar trebui să conțină „SCT” (extensii pentru SCT), „STH” (extensii pentru STH) sau ambele. Experții desemnați ar trebui să verifice specificația publică și adecvarea extensiei la contextele de utilizare.

10.2.5. ID-uri de jurnal (Log IDs)

Registrul „Log IDs” are procedura First Come First Served. Inițial: 1.3.101.8192–1.3.101.16383 (nealocate) și arcul 1.3.101.80.0–1.3.101.80.* (nealocate). Notă: intervalul 1.3.101.8192–1.3.101.16383 conține 8.192 OID-uri, fiecare cu o lungime codificată de 4 octeți; arcul 1.3.101.80 este nelimitat, dar doar 128 de OID-uri (1.3.101.80.0–1.3.101.80.127) au lungime de 4 octeți.

Fiecare cerere de alocare trebuie însoțită de Base URL-ul jurnalului și de datele de contact ale operatorului. IANA este rugată să respingă cererile de actualizare a Log ID sau Log Base URL (sunt imutabile), dar să accepte actualizări ale datelor de contact. Deoarece operatorii pot alege să nu folosească registrul (Secțiunea 4.4), acesta nu este de așteptat să fie un director global al tuturor jurnalelor.

10.2.6. Tipuri de erori

Registrul „Error Types” are procedura Specification Required și trei câmpuri: Identifier (string), Meaning (string), Reference (string). Valorile inițiale, preluate din Secțiunea 5, sunt:

IdentifierMeaning (tradus)Referință
malformedCererea nu a putut fi parsata.RFC 9162
badSubmissionTrimiterea nu este nici certificat valid, nici precertificat valid.RFC 9162
badTypetype nu este nici 1, nici 2.RFC 9162
badChainPrimul element din chain nu certifică trimiterea, sau al doilea nu îl certifică pe primul etc.RFC 9162
badCertificateUnul sau mai multe certificate din chain nu sunt valide (ex.: codificate incorect).RFC 9162
unknownAnchorUltimul element din chain (sau trimiterea, dacă chain e gol) nu este, și nu este certificat de, o ancoră de încredere acceptată.RFC 9162
shutdownJurnalul nu mai acceptă trimiteri.RFC 9162
firstUnknownfirst este înaintea celui mai recent STH cunoscut, dar nu provine dintr-un STH existent.RFC 9162
secondUnknownsecond este înaintea celui mai recent STH cunoscut, dar nu provine dintr-un STH existent.RFC 9162
secondBeforeFirstsecond este mai mic decât first.RFC 9162
hashUnknownhash nu este hash-ul unei frunze cunoscute (posibil din cauza decalajului sau a unui certificat cunoscut, dar neîmbinat încă).RFC 9162
treeSizeUnknownhash este înaintea celui mai recent STH cunoscut, dar nu provine dintr-un STH existent.RFC 9162
startUnknownstart este mai mare decât numărul de înregistrări din arborele Merkle.RFC 9162
endBeforeStartstart nu poate fi mai mare decât end.RFC 9162

10.3. Alocarea OID

IANA a alocat un identificator de obiect din registrul „SMI Security for PKIX Module Identifier” pentru modulul ASN.1 din Anexa B:

ZecimalDescriereReferințe
102id-mod-public-notary-v2RFC 9162
13

Considerații de securitate

Cu CA, jurnale și servere care execută acțiunile descrise aici, clienții TLS pot folosi jurnalele și mărcile temporale semnate pentru a reduce probabilitatea de a accepta certificate emise fraudulos. Dacă un server prezintă o marcă temporală semnată validă pentru un certificat, clientul știe că un jurnal s-a angajat să publice certificatul. De aici, clientul știe că monitorii care acționează pentru subiectul certificatului au avut timp să observe emiterea frauduloasă și să acționeze (de exemplu, cerând CA revocarea). O marcă temporală nu garantează însă acest lucru: monitorii pot să nu fi verificat jurnalele, iar CA poate refuza revocarea.

În plus, dacă clienții TLS nu acceptă certificate neînregistrate, proprietarii de site-uri vor avea un stimulent mai mare să trimită certificatele la jurnale, eventual cu ajutorul CA, crescând transparența generală a sistemului.

11.1. Certificate emise fraudulos

Certificatele emise fraudulos care nu au fost înregistrate public și nu au un SCT valid nu sunt considerate conforme. Cele care au un SCT vor apărea în jurnalul public în Maximum Merge Delay, presupunând că jurnalul funcționează corect. Deoarece un jurnal poate servi un STH de orice vechime până la MMD, perioada maximă în care un certificat fraudulos poate fi folosit fără a fi disponibil pentru audit este de două ori MMD.

11.2. Detectarea emiterii frauduloase

Jurnalele nu detectează ele însele certificatele emise fraudulos; se bazează pe părțile interesate (de exemplu, proprietarii de domenii) să le monitorizeze și să ia măsuri corective.

11.3. Jurnale care se comportă greșit

Un jurnal se poate comporta greșit în mai multe moduri: neîncorporarea unui certificat cu SCT în arbore în MMD; prezentarea unor vederi diferite, conflictuale, la momente diferite și/sau unor părți diferite; emiterea STH-urilor prea des; mutarea semnăturii unui certificat înregistrat; neprezentarea lanțului care conține certificatorul unui certificat înregistrat.

Încălcarea contractului MMD este detectată de clienții care cer o dovadă Merkle de includere (5.4) pentru fiecare SCT observat; verificările pot fi asincrone și trebuie făcute o singură dată per certificat (dar pot exista preocupări de confidențialitate, Secțiunea 8.1.4).

Încălcarea proprietății append-only sau a limitei de emitere a STH-urilor poate fi detectată de mai mulți clienți care compară instanțele lor de STH. Această tehnică, cunoscută ca „gossip”, este un domeniu activ de cercetare și nu este definită aici. Dovada ar fi o serie de STH-uri emise prea aproape (încălcarea limitei de rată) sau un STH cu un root hash care nu se potrivește cu cel calculat dintr-o copie a jurnalului (încălcarea append-only).

Clienții care raportează SCT-uri pot fi urmăriți dacă un jurnal produce mai multe STH-uri sau SCT-uri cu aceeași marcă temporală și aceleași date, dar semnături diferite. Jurnalele ar trebui să reducă acest risc fie folosind scheme de semnătură deterministe, fie producând cel mult un SCT pentru fiecare trimitere distinctă și cel mult un STH pentru fiecare tree_size distinct, stocându-le și servindu-le și altor clienți.

11.4. SCT-uri multiple

Cerând serverelor TLS să ofere SCT-uri multiple, fiecare de la un jurnal diferit, clienții TLS reduc eficacitatea unui atac în care o CA și un jurnal colaborează (Secțiunea 6.2).

11.5. Scurgerea de informații DNS

Monitorii rău-intenționați pot folosi jurnalele pentru a afla existența unor nume de domenii greu de descoperit altfel. Unele etichete de subdomeniu pot dezvălui informații despre serviciul și software-ul pentru care este folosit subdomeniul, ceea ce ar putea facilita atacuri țintite.

14

Referințe

12.1. Referințe normative

MarcăReferință
[FIPS186-4]National Institute of Standards and Technology, „Digital Signature Standard (DSS)”, FIPS PUB 186-4, iulie 2013.
[HTML401]Raggett, D., Le Hors, A. și I. Jacobs, „HTML 4.01 Specification”, W3C Recommendation, martie 2018.
[RFC2119]Bradner, S., „Key words for use in RFCs to Indicate Requirement Levels”, BCP 14, RFC 2119, martie 1997.
[RFC3553]Mealling, M., Masinter, L., Hardie, T. și G. Klyne, „An IETF URN Sub-namespace for Registered Protocol Parameters”, BCP 73, RFC 3553, iunie 2003.
[RFC3986]Berners-Lee, T., Fielding, R. și L. Masinter, „Uniform Resource Identifier (URI): Generic Syntax”, STD 66, RFC 3986, ianuarie 2005.
[RFC4648]Josefsson, S., „The Base16, Base32, and Base64 Data Encodings”, RFC 4648, octombrie 2006.
[RFC5246]Dierks, T. și E. Rescorla, „The Transport Layer Security (TLS) Protocol Version 1.2”, RFC 5246, august 2008.
[RFC5280]Cooper, D., Santesson, S., Farrell, S., Boeyen, S., Housley, R. și W. Polk, „Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile”, RFC 5280, mai 2008.
[RFC5652]Housley, R., „Cryptographic Message Syntax (CMS)”, STD 70, RFC 5652, septembrie 2009.
[RFC6066]Eastlake 3rd, D., „Transport Layer Security (TLS) Extensions: Extension Definitions”, RFC 6066, ianuarie 2011.
[RFC6234]Eastlake 3rd, D. și T. Hansen, „US Secure Hash Algorithms (SHA and SHA-based HMAC and HKDF)”, RFC 6234, mai 2011.
[RFC6960]Santesson, S., Myers, M., Ankney, R., Malpani, A., Galperin, S. și C. Adams, „X.509 Internet Public Key Infrastructure Online Certificate Status Protocol – OCSP”, RFC 6960, iunie 2013.
[RFC6979]Pornin, T., „Deterministic Usage of the Digital Signature Algorithm (DSA) and Elliptic Curve Digital Signature Algorithm (ECDSA)”, RFC 6979, august 2013.
[RFC7231]Fielding, R. (ed.) și J. Reschke (ed.), „Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content”, RFC 7231, iunie 2014.
[RFC7633]Hallam-Baker, P., „X.509v3 Transport Layer Security (TLS) Feature Extension”, RFC 7633, octombrie 2015.
[RFC7807]Nottingham, M. și E. Wilde, „Problem Details for HTTP APIs”, RFC 7807, martie 2016.
[RFC8032]Josefsson, S. și I. Liusvaara, „Edwards-Curve Digital Signature Algorithm (EdDSA)”, RFC 8032, ianuarie 2017.
[RFC8174]Leiba, B., „Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words”, BCP 14, RFC 8174, mai 2017.
[RFC8259]Bray, T. (ed.), „The JavaScript Object Notation (JSON) Data Interchange Format”, STD 90, RFC 8259, decembrie 2017.
[RFC8391]Huelsing, A., Butin, D., Gazdag, S., Rijneveld, J. și A. Mohaisen, „XMSS: eXtended Merkle Signature Scheme”, RFC 8391, mai 2018.
[RFC8446]Rescorla, E., „The Transport Layer Security (TLS) Protocol Version 1.3”, RFC 8446, august 2018.
[UNIXTIME]IEEE, „The Open Group Base Specifications Issue 7”, secțiunea 4.16 „Seconds Since the Epoch”, IEEE Std 1003.1-2008, 2016.
[X690]ITU-T, „Information technology – ASN.1 encoding rules: BER, CER and DER”, Recomandarea ITU-T X.690, ISO/IEC 8825-1, februarie 2021.

12.2. Referințe informative

MarcăReferință
[CABBR]CA/Browser Forum, „Baseline Requirements for the Issuance and Management of Publicly-Trusted Certificates”, versiunea 1.7.3, octombrie 2020.
[Chromium.Log.Policy]The Chromium Projects, „Chromium Certificate Transparency Log Policy”.
[Chromium.Policy]The Chromium Projects, „Chromium Certificate Transparency Policy”.
[CrosbyWallach]Crosby, S. și D. Wallach, „Efficient Data Structures for Tamper-Evident Logging”, Proceedings of the 18th USENIX Security Symposium, Montreal, august 2009.
[JSON.Metadata]The Chromium Projects, „Chromium Log Metadata JSON Schema”.
[RFC5912]Hoffman, P. și J. Schaad, „New ASN.1 Modules for the Public Key Infrastructure Using X.509 (PKIX)”, RFC 5912, iunie 2010.
[RFC6268]Schaad, J. și S. Turner, „Additional New ASN.1 Modules for the Cryptographic Message Syntax (CMS) and the Public Key Infrastructure Using X.509 (PKIX)”, RFC 6268, iulie 2011.
[RFC6962]Laurie, B., Langley, A. și E. Kasper, „Certificate Transparency”, RFC 6962, iunie 2013.
[RFC8126]Cotton, M., Leiba, B. și T. Narten, „Guidelines for Writing an IANA Considerations Section in RFCs”, BCP 26, RFC 8126, iunie 2017.
[RFC8820]Nottingham, M., „URI Design and Ownership”, BCP 190, RFC 8820, iunie 2020.
[X.680]ITU-T, „Information technology – Abstract Syntax Notation One (ASN.1): Specification of basic notation”, Recomandarea ITU-T X.680, februarie 2021.
15

Anexa A. Suport simultan pentru v1 și v2 (informativă)

Jurnalele CT trebuie să fie fie v1 (conforme cu [RFC6962]), fie v2 (conforme cu acest document), deoarece structurile de date sunt incompatibile; un jurnal v2 nu ar putea emite un SCT v1 valid.

Clienții CT pot, însă, suporta simultan SCT-uri v1 și v2 pentru același certificat, deoarece SCT-urile v1 sunt livrate în extensii TLS, X.509 și OCSP diferite față de SCT-urile v2.

SCT-urile v1 și v2 pentru certificate X.509 pot fi validate independent. Pentru precertificate, SCT-urile v2 ar trebui încorporate în TBSCertificate înainte de trimiterea TBSCertificate (în interiorul unui precertificat v1, conform Secțiunii 3.1 din [RFC6962]) către un jurnal v1, astfel încât clienții TLS conformi cu [RFC6962], dar nu cu acest document, să nu fie deranjați de SCT-urile v2 încorporate. Un emitent poate produce un certificat X.509 cu SCT-uri v1 și v2 încorporate urmând pașii:

  1. Creează un precertificat CMS (Secțiunea 3.2) și îl trimite la jurnale v2.
  2. Încorporează SCT-urile v2 obținute în TBSCertificate (Secțiunea 7.1.2).
  3. Folosește acel TBSCertificate pentru a crea un precertificat v1 (Secțiunea 3.1 din [RFC6962]) și îl trimite la jurnale v1.
  4. Încorporează SCT-urile v1 în TBSCertificate (Secțiunea 3.3 din [RFC6962]).
  5. Semnează acel TBSCertificate (care conține acum SCT-uri v1 și v2) pentru a emite certificatul X.509 final.
16

Anexa B. Modul ASN.1 (informativă)

Următorul modul ASN.1 [X.680] poate fi util implementatorilor. Modulul referă [RFC5912] și [RFC6268].

CertificateTransparencyV2Module-2021
 -- { id-mod-public-notary-v2 din secțiunea 10.3 }
DEFINITIONS IMPLICIT TAGS ::= BEGIN

IMPORTS
  EXTENSION FROM PKIX-CommonTypes-2009        -- RFC 5912
  CONTENT-TYPE FROM CryptographicMessageSyntax-2010 -- RFC 6268
  TBSCertificate FROM PKIX1Explicit-2009      -- RFC 5912
;

-- Secțiunea 3.2. Precertificate
ct-tbsCertificate CONTENT-TYPE ::= {
  TYPE TBSCertificate
  IDENTIFIED BY id-ct-tbsCertificate }
id-ct-tbsCertificate OBJECT IDENTIFIER ::= { 1 3 101 78 }

-- Secțiunea 7.1. Extensia X.509v3 Transparency Information
ext-transparencyInfo EXTENSION ::= {
  SYNTAX TransparencyInformationSyntax
  IDENTIFIED BY id-ce-transparencyInfo
  CRITICALITY { FALSE } }
id-ce-transparencyInfo OBJECT IDENTIFIER ::= { 1 3 101 75 }
TransparencyInformationSyntax ::= OCTET STRING

-- Secțiunea 7.1.1. Extensie în răspunsul OCSP
ext-ocsp-transparencyInfo EXTENSION ::= {
  SYNTAX TransparencyInformationSyntax
  IDENTIFIED BY id-pkix-ocsp-transparencyInfo
  CRITICALITY { FALSE } }
id-pkix-ocsp-transparencyInfo OBJECT IDENTIFIER ::=
  id-ce-transparencyInfo

-- Secțiunea 8.1.2. Reconstruirea TBSCertificate
ext-embeddedSCT-CTv1 EXTENSION ::= {
  SYNTAX SignedCertificateTimestampList
  IDENTIFIED BY id-ce-embeddedSCT-CTv1
  CRITICALITY { FALSE } }
id-ce-embeddedSCT-CTv1 OBJECT IDENTIFIER ::= {
  1 3 6 1 4 1 11129 2 4 2 }
SignedCertificateTimestampList ::= OCTET STRING

END