<?xml version="1.0" encoding="UTF-8"?>
  <?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
  <!-- generated by https://github.com/cabo/kramdown-rfc2629 version 1.0.35 -->

<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [
]>

<?rfc toc="yes"?>
<?rfc sortrefs="yes"?>
<?rfc symrefs="yes"?>

<rfc ipr="trust200902" docName="draft-ietf-trans-rfc6962-bis-20" category="std">

  <front>
    <title>Certificate Transparency</title>

    <author initials="B." surname="Laurie" fullname="Ben Laurie">
      <organization abbrev="Google">Google UK Ltd.</organization>
      <address>
        <email>benl@google.com</email>
      </address>
    </author>
    <author initials="A." surname="Langley" fullname="Adam Langley">
      <organization abbrev="Google">Google Inc.</organization>
      <address>
        <email>agl@google.com</email>
      </address>
    </author>
    <author initials="E." surname="Kasper" fullname="Emilia Kasper">
      <organization abbrev="Google">Google Switzerland GmbH</organization>
      <address>
        <email>ekasper@google.com</email>
      </address>
    </author>
    <author initials="E." surname="Messeri" fullname="Eran Messeri">
      <organization abbrev="Google">Google UK Ltd.</organization>
      <address>
        <email>eranm@google.com</email>
      </address>
    </author>
    <author initials="R." surname="Stradling" fullname="Rob Stradling">
      <organization abbrev="Comodo">Comodo CA, Ltd.</organization>
      <address>
        <email>rob.stradling@comodo.com</email>
      </address>
    </author>

    <date year="2016" month="October" day="31"/>

    <area>Security</area>
    <workgroup>TRANS (Public Notary Transparency)</workgroup>
    

    <abstract>


<t>This document describes a protocol for publicly logging the existence of
Transport Layer Security (TLS) server certificates as they are issued or
observed, in a manner that allows anyone to audit certification authority (CA)
activity and notice the issuance of suspect certificates as well as to audit the
certificate logs themselves. The intent is that eventually clients would refuse
to honor certificates that do not appear in a log, effectively forcing CAs to
add all issued certificates to the logs.</t>

<t>Logs are network services that implement the protocol operations for submissions
and queries that are defined in this document.</t>



    </abstract>


  </front>

  <middle>


<section anchor="introduction" title="Introduction">

<t>Certificate transparency aims to mitigate the problem of misissued certificates
by providing append-only logs of issued certificates. The logs do not need to be
trusted because they are publicly auditable. Anyone may verify the correctness
of each log and monitor when new certificates are added to it. The logs do not
themselves prevent misissue, but they ensure that interested parties
(particularly those named in certificates) can detect such misissuance. Note
that this is a general mechanism that could be used for transparently logging
any form of binary data, subject to some kind of inclusion criteria. In this
document, we only describe its use for public TLS server certificates (i.e.,
where the inclusion criteria is a valid certificate issued by a public
certification authority (CA)).</t>

<t>Each log contains certificate chains, which can be submitted by anyone. It is
expected that public CAs will contribute all their newly issued certificates to
one or more logs; however certificate holders can also contribute their own
certificate chains, as can third parties. In order to avoid logs being rendered
useless by the submission of large numbers of spurious certificates, it is
required that each chain ends with a trust anchor that is accepted by the log.
When a chain is accepted by a log, a signed timestamp is returned, which can
later be used to provide evidence to TLS clients that the chain has been
submitted. TLS clients can thus require that all certificates they accept as
valid are accompanied by signed timestamps.</t>

<t>Those who are concerned about misissuance can monitor the logs, asking them
regularly for all new entries, and can thus check whether domains for which they
are responsible have had certificates issued that they did not expect. What
they do with this information, particularly when they find that a misissuance
has happened, is beyond the scope of this document. However, broadly speaking,
they can invoke existing business mechanisms for dealing with misissued
certificates, such as working with the CA to get the certificate revoked, or
with maintainers of trust anchor lists to get the CA removed. Of course, anyone
who wants can monitor the logs and, if they believe a certificate is incorrectly
issued, take action as they see fit.</t>

<t>Similarly, those who have seen signed timestamps from a particular log can later
demand a proof of inclusion from that log. If the log is unable to provide this
(or, indeed, if the corresponding certificate is absent from monitors' copies of
that log), that is evidence of the incorrect operation of the log. The checking
operation is asynchronous to allow clients to proceed without delay, despite
possible issues such as network connectivity and the vagaries of firewalls.</t>

<t>The append-only property of each log is achieved using Merkle Trees, which can
be used to show that any particular instance of the log is a superset of any
particular previous instance. Likewise, Merkle Trees avoid the need to blindly
trust logs: if a log attempts to show different things to different people, this
can be efficiently detected by comparing tree roots and consistency proofs.
Similarly, other misbehaviors of any log (e.g., issuing signed timestamps for
certificates they then don't log) can be efficiently detected and proved to the
world at large.</t>

<section anchor="requirements-language" title="Requirements Language">

<t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD",
"SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be
interpreted as described in RFC 2119 <xref target="RFC2119"></xref>.</t>

</section>
<section anchor="data-structures" title="Data Structures">

<t>Data structures are defined according to the conventions laid out in Section 4
of <xref target="RFC5246"></xref>.</t>

</section>
</section>
<section anchor="cryptographic-components" title="Cryptographic Components">

<section anchor="mht" title="Merkle Hash Trees">

<t>Logs use a binary Merkle Hash Tree for efficient auditing. The hashing algorithm
used by each log is expected to be specified as part of the metadata relating to
that log (see <xref target="metadata"/>). We have established a registry of acceptable
algorithms, see <xref target="hash_algorithms"/>. The hashing algorithm in use is referred to
as HASH throughout this document and the size of its output in bytes as
HASH_SIZE. The input to the Merkle Tree Hash is a list of data entries; these
entries will be hashed to form the leaves of the Merkle Hash Tree. The output is
a single HASH_SIZE Merkle Tree Hash. Given an ordered list of n inputs, D[n] =
{d(0), d(1), …, d(n-1)}, the Merkle Tree Hash (MTH) is thus defined as
follows:</t>

<t>The hash of an empty list is the hash of an empty string:</t>

<figure><artwork><![CDATA[
MTH({}) = HASH().
]]></artwork></figure>

<t>The hash of a list with one entry (also known as a leaf hash) is:</t>

<figure><artwork><![CDATA[
MTH({d(0)}) = HASH(0x00 || d(0)).
]]></artwork></figure>

<t>For n &gt; 1, let k be the largest power of two smaller than n
(i.e., k &lt; n &lt;= 2k).
The Merkle Tree Hash of an n-element list D[n] is then defined recursively as</t>

<figure><artwork><![CDATA[
MTH(D[n]) = HASH(0x01 || MTH(D[0:k]) || MTH(D[k:n])),
]]></artwork></figure>

<t>where || is concatenation and D[k1:k2] denotes the list {d(k1), d(k1+1), …,
d(k2-1)} of length (k2 - k1). (Note that the hash calculations for leaves and
nodes differ. This domain separation is required to give second preimage
resistance.)</t>

<t>Note that we do not require the length of the input list to be a power of two.
The resulting Merkle Tree may thus not be balanced; however, its shape is
uniquely determined by the number of leaves. (Note: This Merkle Tree is
essentially the same as the history tree <xref target="CrosbyWallach"></xref> proposal, except our
definition handles non-full trees differently.)</t>

<section anchor="merkle_inclusion_proof" title="Merkle Inclusion Proofs">

<t>A Merkle inclusion proof for a leaf in a Merkle Hash Tree is the shortest list
of additional nodes in the Merkle Tree required to compute the Merkle Tree Hash
for that tree. Each node in the tree is either a leaf node or is computed from
the two nodes immediately below it (i.e., towards the leaves). At each step up
the tree (towards the root), a node from the inclusion proof is combined with
the node computed so far. In other words, the inclusion proof consists of the
list of missing nodes required to compute the nodes leading from a leaf to the
root of the tree. If the root computed from the inclusion proof matches the true
root, then the inclusion proof proves that the leaf exists in the tree.</t>

<t>Given an ordered list of n inputs to the tree, D[n] = {d(0), …, d(n-1)}, the
Merkle inclusion proof PATH(m, D[n]) for the (m+1)th input d(m), 0 &lt;= m &lt; n,
is defined as follows:</t>

<t>The proof for the single leaf in a tree with a one-element input list D[1] =
{d(0)} is empty:</t>

<figure><artwork><![CDATA[
PATH(0, {d(0)}) = {}
]]></artwork></figure>

<t>For n &gt; 1, let k be the largest power of two smaller than n. The proof for the
(m+1)th element d(m) in a list of n &gt; m elements is then defined recursively as</t>

<figure><artwork><![CDATA[
PATH(m, D[n]) = PATH(m, D[0:k]) : MTH(D[k:n]) for m < k; and

PATH(m, D[n]) = PATH(m - k, D[k:n]) : MTH(D[0:k]) for m >= k,
]]></artwork></figure>

<t>where : is concatenation of lists and D[k1:k2] denotes the length (k2 - k1)
list {d(k1), d(k1+1),…, d(k2-1)} as before.</t>

</section>
<section anchor="consistency" title="Merkle Consistency Proofs">

<t>Merkle consistency proofs prove the append-only property of the tree. A Merkle
consistency proof for a Merkle Tree Hash MTH(D[n]) and a previously advertised
hash MTH(D[0:m]) of the first m leaves, m &lt;= n, is the list of nodes in the
Merkle Tree required to verify that the first m inputs D[0:m] are equal in both
trees. Thus, a consistency proof must contain a set of intermediate nodes (i.e.,
commitments to inputs) sufficient to verify MTH(D[n]), such that (a subset of)
the same nodes can be used to verify MTH(D[0:m]). We define an algorithm that
outputs the (unique) minimal consistency proof.</t>

<t>Given an ordered list of n inputs to the tree, D[n] = {d(0), …, d(n-1)}, the
Merkle consistency proof PROOF(m, D[n]) for a previous Merkle Tree Hash
MTH(D[0:m]), 0 &lt; m &lt; n, is defined as:</t>

<figure><artwork><![CDATA[
PROOF(m, D[n]) = SUBPROOF(m, D[n], true)
]]></artwork></figure>

<t>In SUBPROOF, the boolean value represents whether the subtree created from
D[0:m] is a complete subtree of the Merkle Tree created from D[n], and,
consequently, whether the subtree Merkle Tree Hash MTH(D[0:m]) is known. The
initial call to SUBPROOF sets this to be true, and SUBPROOF is then defined as
follows:</t>

<t>The subproof for m = n is empty if m is the value for which PROOF was originally
requested (meaning that the subtree created from D[0:m] is a complete subtree
of the Merkle Tree created from the original D[n] for which PROOF was
requested, and the subtree Merkle Tree Hash MTH(D[0:m]) is known):</t>

<figure><artwork><![CDATA[
SUBPROOF(m, D[m], true) = {}
]]></artwork></figure>

<t>Otherwise, the subproof for m = n is the Merkle Tree Hash committing inputs
D[0:m]:</t>

<figure><artwork><![CDATA[
SUBPROOF(m, D[m], false) = {MTH(D[m])}
]]></artwork></figure>

<t>For m &lt; n, let k be the largest power of two smaller than n. The subproof is
then defined recursively.</t>

<t>If m &lt;= k, the right subtree entries D[k:n] only exist in the current tree.
We prove that the left subtree entries D[0:k] are consistent and add a
commitment to D[k:n]:</t>

<figure><artwork><![CDATA[
SUBPROOF(m, D[n], b) = SUBPROOF(m, D[0:k], b) : MTH(D[k:n])
]]></artwork></figure>

<t>If m &gt; k, the left subtree entries D[0:k] are identical in both trees. We prove
that the right subtree entries D[k:n] are consistent and add a commitment to
D[0:k].</t>

<figure><artwork><![CDATA[
SUBPROOF(m, D[n], b) = SUBPROOF(m - k, D[k:n], false) : MTH(D[0:k])
]]></artwork></figure>

<t>Here, : is a concatenation of lists, and D[k1:k2] denotes the length (k2 - k1)
list {d(k1), d(k1+1),…, d(k2-1)} as before.</t>

<t>The number of nodes in the resulting proof is bounded above by ceil(log2(n)) +
1.</t>

</section>
<section anchor="example" title="Example">

<t>The binary Merkle Tree with 7 leaves:</t>

<figure><artwork><![CDATA[
            hash
           /    \
          /      \
         /        \
        /          \
       /            \
      k              l
     / \            / \
    /   \          /   \
   /     \        /     \
  g       h      i      j
 / \     / \    / \     |
 a b     c d    e f     d6
 | |     | |    | |
d0 d1   d2 d3  d4 d5
]]></artwork></figure>

<t>The inclusion proof for d0 is [b, h, l].</t>

<t>The inclusion proof for d3 is [c, g, l].</t>

<t>The inclusion proof for d4 is [f, j, k].</t>

<t>The inclusion proof for d6 is [i, k].</t>

<t>The same tree, built incrementally in four steps:</t>

<figure><artwork><![CDATA[
    hash0          hash1=k
    / \              /  \
   /   \            /    \
  /     \          /      \
  g      c         g       h
 / \     |        / \     / \
 a b     d2       a b     c d
 | |              | |     | |
d0 d1            d0 d1   d2 d3

          hash2                    hash
          /  \                    /    \
         /    \                  /      \
        /      \                /        \
       /        \              /          \
      /          \            /            \
     k            i          k              l
    / \          / \        / \            / \
   /   \         e f       /   \          /   \
  /     \        | |      /     \        /     \
 g       h      d4 d5    g       h      i      j
/ \     / \             / \     / \    / \     |
a b     c d             a b     c d    e f     d6
| |     | |             | |     | |    | |
d0 d1   d2 d3           d0 d1   d2 d3  d4 d5
]]></artwork></figure>

<t>The consistency proof between hash0 and hash is PROOF(3, D[7]) = [c, d, g, l].
c, g are used to verify hash0, and d, l are additionally used to show hash is
consistent with hash0.</t>

<t>The consistency proof between hash1 and hash is PROOF(4, D[7]) = [l]. hash can
be verified using hash1=k and l.</t>

<t>The consistency proof between hash2 and hash is PROOF(6, D[7]) = [i, j, k].
k, i are used to verify hash2, and j is additionally used to show hash is
consistent with hash2.</t>

</section>
<section anchor="signatures" title="Signatures">

<t>Various data structures are signed. A log MUST use one of the signature
algorithms defined in <xref target="signature_algorithms"/>.</t>

</section>
</section>
</section>
<section anchor="submitters" title="Submitters">

<t>Submitters submit certificates or preannouncements of certificates prior to
issuance (precertificates) to logs for public auditing, as described below. In
order to enable attribution of each logged certificate or precertificate to its
issuer, each submission MUST be accompanied by all additional certificates
required to verify the chain up to an accepted trust anchor. The trust anchor (a
root or intermediate CA certificate) MAY be omitted from the submission.</t>

<t>If a log accepts a submission, it will return a Signed Certificate Timestamp
(SCT) (see <xref target="sct"/>). The submitter SHOULD validate the returned SCT as described
in <xref target="tls_clients"/> if they understand its format and they intend to use it
directly in a TLS handshake or to construct a certificate. If the submitter does
not need the SCT (for example, the certificate is being submitted simply to make
it available in the log), it MAY validate the SCT.</t>

<section anchor="certificates" title="Certificates">

<t>Any entity can submit a certificate (<xref target="add-chain"/>) to a log. Since it is
anticipated that TLS clients will reject certificates that are not logged, it is
expected that certificate issuers and subjects will be strongly motivated to
submit them.</t>

</section>
<section anchor="precertificates" title="Precertificates">

<t>CAs may preannounce a certificate prior to issuance by submitting a
precertificate (<xref target="add-pre-chain"/>) that the log can use to create an entry that
will be valid against the issued certificate. The CA MAY incorporate the
returned SCT in the issued certificate. One example of where the returned SCT is
not incorporated in the issued certificate is when a CA sends the precertificate
to multiple logs, but only incorporates the SCTs that are returned first.</t>

<t>A precertificate is a CMS <xref target="RFC5652"></xref> <spanx style="verb">signed-data</spanx> object that conforms to the
following requirements:</t>

<t><list style="symbols">
  <t>It MUST be DER encoded.</t>
  <t><spanx style="verb">SignedData.encapContentInfo.eContentType</spanx> MUST be the OID 1.3.101.78.</t>
  <t><spanx style="verb">SignedData.encapContentInfo.eContent</spanx> MUST contain a TBSCertificate <xref target="RFC5280"></xref>
that will be identical to the TBSCertificate in the issued certificate, except
that the Transparency Information (<xref target="x509v3_transinfo_extension"/>) extension
MUST be omitted.</t>
  <t><spanx style="verb">SignedData.signerInfos</spanx> MUST contain a signature from the same (root or
intermediate) CA that will ultimately issue the certificate. This signature
indicates the CA's intent to issue the certificate. This intent is considered
binding (i.e., misissuance of the precertificate is considered equivalent to
misissuance of the certificate). (Note that, because of the structure of CMS,
the signature on the CMS object will not be a valid X.509v3 signature and so
cannot be used to construct a certificate from the precertificate).</t>
  <t><spanx style="verb">SignedData.certificates</spanx> SHOULD be omitted.</t>
</list></t>

</section>
</section>
<section anchor="private-domain-name-labels" title="Private Domain Name Labels">

<t>Some regard certain DNS domain name labels within their registered domain space
as private and security sensitive. Even though these domains are often only
accessible within the domain owner's private network, it's common for them to be
secured using publicly trusted TLS server certificates.</t>

<section anchor="wildcard-certificates" title="Wildcard Certificates">

<t>A certificate containing a DNS-ID <xref target="RFC6125"></xref> of <spanx style="verb">*.example.com</spanx> could be used to
secure the domain <spanx style="verb">topsecret.example.com</spanx>, without revealing the string
<spanx style="verb">topsecret</spanx> publicly.</t>

<t>Since TLS clients only match the wildcard character to the complete leftmost
label of the DNS domain name (see Section 6.4.3 of <xref target="RFC6125"></xref>), a different
approach is needed when any label other than the leftmost label in a DNS-ID is
considered private (e.g., <spanx style="verb">top.secret.example.com</spanx>). Also, wildcard certificates
are prohibited in some cases, such as Extended Validation Certificates
<xref target="EVSSLGuidelines"></xref>.</t>

</section>
<section anchor="name_constrained" title="Using a Name-Constrained Intermediate CA">

<t>An intermediate CA certificate or intermediate CA precertificate that contains
the Name Constraints <xref target="RFC5280"></xref> extension MAY be logged in place of end-entity
certificates issued by that intermediate CA, as long as all of the following
conditions are met:</t>

<t><list style="symbols">
  <t>there MUST be a non-critical extension (OID 1.3.101.76, whose extnValue OCTET
STRING contains ASN.1 NULL data (0x05 0x00)). This extension is an explicit
indication that it is acceptable to not log certificates issued by this
intermediate CA.</t>
  <t>there MUST be a Name Constraints extension, in which:  <list style="symbols">
      <t>permittedSubtrees MUST specify one or more dNSNames.</t>
      <t>excludedSubtrees MUST specify the entire IPv4 and IPv6 address ranges.</t>
    </list></t>
</list></t>

<t>Below is an example Name Constraints extension that meets these conditions:</t>

<figure><artwork><![CDATA[
    SEQUENCE {
      OBJECT IDENTIFIER '2 5 29 30'
      OCTET STRING, encapsulates {
        SEQUENCE {
          [0] {
            SEQUENCE {
              [2] 'example.com'
              }
            }
          [1] {
            SEQUENCE {
              [7] 00 00 00 00 00 00 00 00
              }
            SEQUENCE {
              [7]
                00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
                00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
              }
            }
          }
        }
      }
]]></artwork></figure>

</section>
</section>
<section anchor="log-format-and-operation" title="Log Format and Operation">

<t>A log is a single, append-only Merkle Tree of submitted certificate and
precertificate entries.</t>

<t>When it receives a valid submission, the log MUST return an SCT that corresponds
to the submitted certificate or precertificate. If the log has previously seen
this valid submission, it SHOULD return the same SCT as it returned before (to
reduce the ability to track clients as described in
<xref target="deterministic_signatures"/>). If different SCTs are produced for the same
submission, multiple log entries will have to be created, one for each SCT (as
the timestamp is a part of the leaf structure). Note that if a certificate was
previously logged as a precertificate, then the precertificate's SCT of type
<spanx style="verb">precert_sct_v2</spanx> would not be appropriate; instead, a fresh SCT of type
<spanx style="verb">x509_sct_v2</spanx> should be generated.</t>

<t>An SCT is the log's promise to incorporate the submitted entry in its Merkle
Tree no later than a fixed amount of time, known as the Maximum Merge Delay
(MMD), after the issuance of the SCT. Periodically, the log MUST append all its
new entries to its Merkle Tree and sign the root of the tree.</t>

<t>Log operators MUST NOT impose any conditions on retrieving or sharing data from
the log.</t>

<section anchor="accepting-submissions" title="Accepting Submissions">

<t>Logs MUST verify that each submitted certificate or precertificate has a valid
signature chain to an accepted trust anchor, using the chain of intermediate CA
certificates provided by the submitter. Logs MUST accept certificates and
precertificates that are fully valid according to RFC 5280 <xref target="RFC5280"></xref>
verification rules and are submitted with such a chain. Logs MAY accept
certificates and precertificates that have expired, are not yet valid, have been
revoked, or are otherwise not fully valid according to RFC 5280 verification
rules in order to accommodate quirks of CA certificate-issuing software.
However, logs MUST reject submissions without a valid signature chain to an
accepted trust anchor. Logs MUST also reject precertificates that do not conform
to the requirements in <xref target="precertificates"/>.</t>

<t>Logs SHOULD limit the length of chain they will accept. The maximum chain length
is specified in the log's metadata.</t>

<t>The log SHALL allow retrieval of its list of accepted trust anchors (see
<xref target="get-anchors"/>), each of which is a root or intermediate CA certificate. This
list might usefully be the union of root certificates trusted by major browser
vendors.</t>

</section>
<section anchor="log_entries" title="Log Entries">

<t>If a submission is accepted and an SCT issued, the accepting log MUST store the
entire chain used for verification. This chain MUST include the certificate or
precertificate itself, the zero or more intermediate CA certificates provided by
the submitter, and the trust anchor used to verify the chain (even if it was
omitted from the submission). The log MUST present this chain for auditing upon
request (see <xref target="get-entries"/>). This chain is required to prevent a CA from
avoiding blame by logging a partial or empty chain.</t>

<t>Each certificate entry in a log MUST include a <spanx style="verb">X509ChainEntry</spanx> structure, and
each precertificate entry MUST include a <spanx style="verb">PrecertChainEntryV2</spanx> structure:</t>

<figure><artwork><![CDATA[
    opaque ASN.1Cert<1..2^24-1>;

    struct {
        ASN.1Cert leaf_certificate;
        ASN.1Cert certificate_chain<0..2^24-1>;
    } X509ChainEntry;

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

    struct {
        CMSPrecert pre_certificate;
        ASN.1Cert precertificate_chain<1..2^24-1>;
    } PrecertChainEntryV2;
]]></artwork></figure>

<t><spanx style="verb">leaf_certificate</spanx> is a submitted certificate that has been accepted by the log.</t>

<t><spanx style="verb">certificate_chain</spanx> is a vector of 0 or more additional certificates required to
verify <spanx style="verb">leaf_certificate</spanx>. The first certificate MUST certify
<spanx style="verb">leaf_certificate</spanx>. Each following certificate MUST directly certify the one
preceding it. The final certificate MUST be a trust anchor accepted by the log.
If <spanx style="verb">leaf_certificate</spanx> is an accepted trust anchor, then this vector is empty.</t>

<t><spanx style="verb">pre_certificate</spanx> is a submitted precertificate that has been accepted by the
log.</t>

<t><spanx style="verb">precertificate_chain</spanx> is a vector of 1 or more additional certificates required
to verify <spanx style="verb">pre_certificate</spanx>. The first certificate MUST certify
<spanx style="verb">pre_certificate</spanx>. Each following certificate MUST directly certify the one
preceding it. The final certificate MUST be a trust anchor accepted by the log.</t>

</section>
<section anchor="log_id" title="Log ID">

<t>Each log is identified by an OID, which is specified in the log's metadata and
which MUST NOT be used to identify any other log. A log's operator MUST either
allocate the OID themselves or request an OID from one of the two Log ID
Registries (see <xref target="log_id_registry1"/> and <xref target="log_id_registry2"/>). Various data
structures include the DER encoding of this OID, excluding the ASN.1 tag and
length bytes, in an opaque vector:</t>

<figure><artwork><![CDATA[
    opaque LogID<2..127>;
]]></artwork></figure>

<t>Note that the ASN.1 length and the opaque vector length are identical in size (1
byte) and value, so the DER encoding of the OID can be reproduced simply by
prepending an OBJECT IDENTIFIER tag (0x06) to the opaque vector length and
contents.</t>

<t>OIDs used to identify logs are limited such that the DER encoding of their value
is less than or equal to 127 octets.</t>

</section>
<section anchor="transitem-structure" title="TransItem Structure">

<t>Various data structures are encapsulated in the <spanx style="verb">TransItem</spanx> structure to ensure
that the type and version of each one is identified in a common fashion:</t>

<figure><artwork><![CDATA[
    enum {
        reserved(0),
        x509_entry_v2(1), precert_entry_v2(2),
        x509_sct_v2(3), precert_sct_v2(4),
        signed_tree_head_v2(5), consistency_proof_v2(6),
        inclusion_proof_v2(7), x509_sct_with_proof_v2(8),
        precert_sct_with_proof_v2(9),
        (65535)
    } 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;
            case x509_sct_with_proof_v2: SCTWithProofDataV2;
            case precert_sct_with_proof_v2: SCTWithProofDataV2;
        } data;
    } TransItem;
]]></artwork></figure>

<t><spanx style="verb">versioned_type</spanx> is the type of the encapsulated data structure and the earliest
version of this protocol to which it conforms. This document is v2.</t>

<t><spanx style="verb">data</spanx> is the encapsulated data structure. The various structures named with the
<spanx style="verb">DataV2</spanx> suffix are defined in later sections of this document.</t>

<t>Note that <spanx style="verb">VersionedTransType</spanx> combines the v1 <xref target="RFC6962"></xref> type enumerations
<spanx style="verb">Version</spanx>, <spanx style="verb">LogEntryType</spanx>, <spanx style="verb">SignatureType</spanx> and <spanx style="verb">MerkleLeafType</spanx>. Note also that
v1 did not define <spanx style="verb">TransItem</spanx>, but this document provides guidelines (see
<xref target="v1_coexistence"/>) on how v2 implementations can co-exist with v1
implementations.</t>

<t>Future versions of this protocol may reuse <spanx style="verb">VersionedTransType</spanx> values defined
in this document as long as the corresponding data structures are not modified,
and may add new <spanx style="verb">VersionedTransType</spanx> values for new or modified data structures.</t>

</section>
<section anchor="tree_leaves" title="Merkle Tree Leaves">

<t>The leaves of a log's Merkle Tree correspond to the log's entries (see
<xref target="log_entries"/>). Each leaf is the leaf hash (<xref target="mht"/>) of a <spanx style="verb">TransItem</spanx>
structure of type <spanx style="verb">x509_entry_v2</spanx> or <spanx style="verb">precert_entry_v2</spanx>, which encapsulates a
<spanx style="verb">TimestampedCertificateEntryDataV2</spanx> structure. Note that leaf hashes are
calculated as HASH(0x00 || TransItem), where the hashing algorithm is specified
in the log's metadata.</t>

<figure><artwork><![CDATA[
    opaque TBSCertificate<1..2^24-1>;

    struct {
        uint64 timestamp;
        opaque issuer_key_hash<32..2^8-1>;
        TBSCertificate tbs_certificate;
        SctExtension sct_extensions<0..2^16-1>;
    } TimestampedCertificateEntryDataV2;
]]></artwork></figure>

<t><spanx style="verb">timestamp</spanx> is the NTP Time <xref target="RFC5905"></xref> at which the certificate or precertificate
was accepted by the log, measured in milliseconds since the epoch (January 1,
1970, 00:00 UTC), ignoring leap seconds. Note that the leaves of a log's Merkle
Tree are not required to be in strict chronological order.</t>

<t><spanx style="verb">issuer_key_hash</spanx> is the HASH of the public key of the CA that issued the
certificate or precertificate, calculated over the DER encoding of the key
represented as SubjectPublicKeyInfo <xref target="RFC5280"></xref>. This is needed to bind the CA to
the certificate or precertificate, making it impossible for the corresponding
SCT to be valid for any other certificate or precertificate whose TBSCertificate
matches <spanx style="verb">tbs_certificate</spanx>. The length of the <spanx style="verb">issuer_key_hash</spanx> MUST match
HASH_SIZE.</t>

<t><spanx style="verb">tbs_certificate</spanx> is the DER encoded TBSCertificate from either the
<spanx style="verb">leaf_certificate</spanx> (in the case of an <spanx style="verb">X509ChainEntry</spanx>) or the <spanx style="verb">pre_certificate</spanx>
(in the case of a <spanx style="verb">PrecertChainEntryV2</spanx>). (Note that a precertificate's
TBSCertificate can be reconstructed from the corresponding certificate as
described in <xref target="reconstructing_tbscertificate"/>).</t>

<t><spanx style="verb">sct_extensions</spanx> matches the SCT extensions of the corresponding SCT.</t>

</section>
<section anchor="sct" title="Signed Certificate Timestamp (SCT)">

<t>An SCT is a <spanx style="verb">TransItem</spanx> structure of type <spanx style="verb">x509_sct_v2</spanx> or <spanx style="verb">precert_sct_v2</spanx>,
which encapsulates a <spanx style="verb">SignedCertificateTimestampDataV2</spanx> structure:</t>

<figure><artwork><![CDATA[
    enum {
        reserved(65535)
    } SctExtensionType;

    struct {
        SctExtensionType sct_extension_type;
        opaque sct_extension_data<0..2^16-1>;
    } SctExtension;

    struct {
        LogID log_id;
        uint64 timestamp;
        SctExtension sct_extensions<0..2^16-1>;
        digitally-signed struct {
            TransItem timestamped_entry;
        } signature;
    } SignedCertificateTimestampDataV2;
]]></artwork></figure>

<t><spanx style="verb">log_id</spanx> is this log's unique ID, encoded in an opaque vector as described in
<xref target="log_id"/>.</t>

<t><spanx style="verb">timestamp</spanx> is equal to the timestamp from the
<spanx style="verb">TimestampedCertificateEntryDataV2</spanx> structure encapsulated in the
<spanx style="verb">timestamped_entry</spanx>.</t>

<t><spanx style="verb">sct_extension_type</spanx> identifies a single extension from the IANA registry in
<xref target="sct_extension_types"/>. At the time of writing, no extensions are specified.</t>

<t>The interpretation of the <spanx style="verb">sct_extension_data</spanx> field is determined solely by the
value of the <spanx style="verb">sct_extension_type</spanx> field. Each document that registers a new
<spanx style="verb">sct_extension_type</spanx> must describe how to interpret the corresponding
<spanx style="verb">sct_extension_data</spanx>.</t>

<t><spanx style="verb">sct_extensions</spanx> is a vector of 0 or more SCT extensions. This vector MUST NOT
include more than one extension with the same <spanx style="verb">sct_extension_type</spanx>. The
extensions in the vector MUST be ordered by the value of the
<spanx style="verb">sct_extension_type</spanx> field, smallest value first. If an implementation sees an
extension that it does not understand, it SHOULD ignore that extension.
Furthermore, an implementation MAY choose to ignore any extension(s) that it
does understand.</t>

<t>The encoding of the digitally-signed element is defined in <xref target="RFC5246"></xref>.</t>

<t><spanx style="verb">timestamped_entry</spanx> is a <spanx style="verb">TransItem</spanx> structure that MUST be of type
<spanx style="verb">x509_entry_v2</spanx> or <spanx style="verb">precert_entry_v2</spanx> (see <xref target="tree_leaves"/>).</t>

</section>
<section anchor="tree_head" title="Merkle Tree Head">

<t>The log stores information about its Merkle Tree in a <spanx style="verb">TreeHeadDataV2</spanx>:</t>

<figure><artwork><![CDATA[
    opaque NodeHash<32..2^8-1>;

    enum {
        reserved(65535)
    } SthExtensionType;

    struct {
        SthExtensionType sth_extension_type;
        opaque sth_extension_data<0..2^16-1>;
    } SthExtension;

    struct {
        uint64 timestamp;
        uint64 tree_size;
        NodeHash root_hash;
        SthExtension sth_extensions<0..2^16-1>;
    } TreeHeadDataV2;
]]></artwork></figure>

<t>The length of NodeHash MUST match HASH_SIZE of the log.</t>

<t><spanx style="verb">sth_extension_type</spanx> identifies a single extension from the IANA registry in
<xref target="sth_extension_types"/>. At the time of writing, no extensions are specified.</t>

<t>The interpretation of the <spanx style="verb">sth_extension_data</spanx> field is determined solely by the
value of the <spanx style="verb">sth_extension_type</spanx> field. Each document that registers a new
<spanx style="verb">sth_extension_type</spanx> must describe how to interpret the corresponding
<spanx style="verb">sth_extension_data</spanx>.</t>

<t><spanx style="verb">timestamp</spanx> is the current NTP Time <xref target="RFC5905"></xref>, measured in milliseconds since
the epoch (January 1, 1970, 00:00 UTC), ignoring leap seconds.</t>

<t><spanx style="verb">tree_size</spanx> is the number of entries currently in the log's Merkle Tree.</t>

<t><spanx style="verb">root_hash</spanx> is the root of the Merkle Hash Tree.</t>

<t><spanx style="verb">sth_extensions</spanx> is a vector of 0 or more STH extensions. This vector MUST NOT
include more than one extension with the same <spanx style="verb">sth_extension_type</spanx>. The
extensions in the vector MUST be ordered by the value of the
<spanx style="verb">sth_extension_type</spanx> field, smallest value first. If an implementation sees an
extension that it does not understand, it SHOULD ignore that extension.
Furthermore, an implementation MAY choose to ignore any extension(s) that it
does understand.</t>

</section>
<section anchor="STH" title="Signed Tree Head (STH)">

<t>Periodically each log SHOULD sign its current tree head information (see
<xref target="tree_head"/>) to produce an STH. When a client requests a log's latest STH (see
<xref target="get-sth"/>), the log MUST return an STH that is no older than the log's MMD.
However, STHs could be used to mark individual clients (by producing a new one
for each query), so logs MUST NOT produce them more frequently than is declared
in their metadata. In general, there is no need to produce a new STH unless
there are new entries in the log; however, in the unlikely event that it
receives no new submissions during an MMD period, the log SHALL sign the same
Merkle Tree Hash with a fresh timestamp.</t>

<t>An STH is a <spanx style="verb">TransItem</spanx> structure of type <spanx style="verb">signed_tree_head_v2</spanx>, which
encapsulates a <spanx style="verb">SignedTreeHeadDataV2</spanx> structure:</t>

<figure><artwork><![CDATA[
    struct {
        LogID log_id;
        TreeHeadDataV2 tree_head;
        digitally-signed struct {
            TreeHeadDataV2 tree_head;
        } signature;
    } SignedTreeHeadDataV2;
]]></artwork></figure>

<t><spanx style="verb">log_id</spanx> is this log's unique ID, encoded in an opaque vector as described in
<xref target="log_id"/>.</t>

<t>The <spanx style="verb">timestamp</spanx> in <spanx style="verb">tree_head</spanx> MUST be at least as recent as the most recent SCT
timestamp in the tree. Each subsequent timestamp MUST be more recent than the
timestamp of the previous update.</t>

<t><spanx style="verb">tree_head</spanx> contains the latest tree head information (see <xref target="tree_head"/>).</t>

<t><spanx style="verb">signature</spanx> is a signature over the encoded <spanx style="verb">tree_head</spanx> field.</t>

</section>
<section anchor="merkle-consistency-proofs" title="Merkle Consistency Proofs">

<t>To prepare a Merkle Consistency Proof for distribution to clients, the log
produces a <spanx style="verb">TransItem</spanx> structure of type <spanx style="verb">consistency_proof_v2</spanx>, which
encapsulates a <spanx style="verb">ConsistencyProofDataV2</spanx> structure:</t>

<figure><artwork><![CDATA[
    struct {
        LogID log_id;
        uint64 tree_size_1;
        uint64 tree_size_2;
        NodeHash consistency_path<1..2^16-1>;
    } ConsistencyProofDataV2;
]]></artwork></figure>

<t><spanx style="verb">log_id</spanx> is this log's unique ID, encoded in an opaque vector as described in
<xref target="log_id"/>.</t>

<t><spanx style="verb">tree_size_1</spanx> is the size of the older tree.</t>

<t><spanx style="verb">tree_size_2</spanx> is the size of the newer tree.</t>

<t><spanx style="verb">consistency_path</spanx> is a vector of Merkle Tree nodes proving the consistency of
two STHs.</t>

</section>
<section anchor="merkle-inclusion-proofs" title="Merkle Inclusion Proofs">

<t>To prepare a Merkle Inclusion Proof for distribution to clients, the log
produces a <spanx style="verb">TransItem</spanx> structure of type <spanx style="verb">inclusion_proof_v2</spanx>, which
encapsulates an <spanx style="verb">InclusionProofDataV2</spanx> structure:</t>

<figure><artwork><![CDATA[
    struct {
        LogID log_id;
        uint64 tree_size;
        uint64 leaf_index;
        NodeHash inclusion_path<1..2^16-1>;
    } InclusionProofDataV2;
]]></artwork></figure>

<t><spanx style="verb">log_id</spanx> is this log's unique ID, encoded in an opaque vector as described in
<xref target="log_id"/>.</t>

<t><spanx style="verb">tree_size</spanx> is the size of the tree on which this inclusion proof is based.</t>

<t><spanx style="verb">leaf_index</spanx> is the 0-based index of the log entry corresponding to this
inclusion proof.</t>

<t><spanx style="verb">inclusion_path</spanx> is a vector of Merkle Tree nodes proving the inclusion of the
chosen certificate or precertificate.</t>

</section>
<section anchor="shutting-down-a-log" title="Shutting down a log">

<t>Log operators may decide to shut down a log for various reasons, such as
deprecation of the signature algorithm. If there are entries in the log for
certificates that have not yet expired, simply making TLS clients stop
recognizing that log will have the effect of invalidating SCTs from that log.
To avoid that, the following actions are suggested:</t>

<t><list style="symbols">
  <t>Make it known to clients and monitors that the log will be frozen.</t>
  <t>Stop accepting new submissions (the error code "shutdown" should be returned
for such requests).</t>
  <t>Once MMD from the last accepted submission has passed and all pending
submissions are incorporated, issue a final STH and publish it as a part of
the log's metadata. Having an STH with a timestamp that is after the MMD has
passed from the last SCT issuance allows clients to audit this log regularly
without special handling for the final STH. At this point the log's private
key is no longer needed and can be destroyed.</t>
  <t>Keep the log running until the certificates in all of its entries have expired
or exist in other logs (this can be determined by scanning other logs or
connecting to domains mentioned in the certificates and inspecting the SCTs
served).</t>
</list></t>

</section>
</section>
<section anchor="client_messages" title="Log Client Messages">

<t>Messages are sent as HTTPS GET or POST requests. Parameters for POSTs and all
responses are encoded as JavaScript Object Notation (JSON) objects <xref target="RFC4627"></xref>.
Parameters for GETs are encoded as order-independent key/value URL parameters,
using the "application/x-www-form-urlencoded" format described in the "HTML 4.01
Specification" <xref target="HTML401"></xref>. Binary data is base64 encoded <xref target="RFC4648"></xref> as specified
in the individual messages.</t>

<t>Note that JSON objects and URL parameters may contain fields not specified here.
These extra fields should be ignored.</t>

<t>The &lt;log server&gt; prefix, which is part of the log's metadata, MAY include a
path as well as a server name and a port.</t>

<t>In practice, log servers may include multiple front-end machines. Since it is
impractical to keep these machines in perfect sync, errors may occur that are
caused by skew between the machines. Where such errors are possible, the
front-end will return additional information (as specified below) making it
possible for clients to make progress, if progress is possible. Front-ends MUST
only serve data that is free of gaps (that is, for example, no front-end will
respond with an STH unless it is also able to prove consistency from all log
entries logged within that STH).</t>

<t>For example, when a consistency proof between two STHs is requested, the
front-end reached may not yet be aware of one or both STHs. In the case where it
is unaware of both, it will return the latest STH it is aware of. Where it is
aware of the first but not the second, it will return the latest STH it is aware
of and a consistency proof from the first STH to the returned STH. The case
where it knows the second but not the first should not arise (see the "no gaps"
requirement above).</t>

<t>If the log is unable to process a client's request, it MUST return an HTTP
response code of 4xx/5xx (see <xref target="RFC2616"></xref>), and, in place of the responses
outlined in the subsections below, the body SHOULD be a JSON structure
containing at least the following field:</t>

<t><list style="hanging">
  <t hangText='error_message:'>
  A human-readable string describing the error which prevented the log from
processing the request.</t>
  <t>In the case of a malformed request, the string SHOULD provide sufficient
detail for the error to be rectified.</t>
  <t hangText='error_code:'>
  An error code readable by the client. Some codes are generic and are detailed
here. Others are detailed in the individual requests. Error codes are fixed
text strings.</t>
</list></t>

<texttable>
      <ttcol align='left'>Error Code</ttcol>
      <ttcol align='left'>Meaning</ttcol>
      <c>not compliant</c>
      <c>The request is not compliant with this RFC.</c>
</texttable>

<t>e.g., In response to a request of <spanx style="verb">/ct/v2/get-entries?start=100&amp;end=99</spanx>, the log
would return a <spanx style="verb">400 Bad Request</spanx> response code with a body similar to the
following:</t>

<figure><artwork><![CDATA[
    {
        "error_message": "'start' cannot be greater than 'end'",
        "error_code": "not compliant",
    }
]]></artwork></figure>

<t>Clients SHOULD treat <spanx style="verb">500 Internal Server Error</spanx> and <spanx style="verb">503 Service Unavailable</spanx>
responses as transient failures and MAY retry the same request without
modification at a later date. Note that as per <xref target="RFC2616"></xref>, in the case of a 503
response the log MAY include a <spanx style="verb">Retry-After:</spanx> header in order to request a
minimum time for the client to wait before retrying the request.</t>

<section anchor="add-chain" title="Add Chain to Log">

<t>POST https://&lt;log server&gt;/ct/v2/add-chain</t>

<t><list style="hanging">
  <t hangText='Inputs:'>
        <list style="hanging">
        <t hangText='chain:'>
        An array of base64 encoded certificates. The first element is the
certificate for which the submitter desires an SCT; the second certifies the
first and so on to the last, which either is, or is certified by, an
accepted trust anchor.</t>
      </list>
  </t>
  <t hangText='Outputs:'>
        <list style="hanging">
        <t hangText='sct:'>
        A base64 encoded <spanx style="verb">TransItem</spanx> of type <spanx style="verb">x509_sct_v2</spanx>, signed by this log, that
corresponds to the submitted certificate.</t>
      </list>
  </t>
</list></t>

<t>Error codes:</t>

<texttable>
      <ttcol align='left'>Error Code</ttcol>
      <ttcol align='left'>Meaning</ttcol>
      <c>unknown anchor</c>
      <c>The last certificate in the chain both is not, and is not certified by, an accepted trust anchor.</c>
      <c>bad chain</c>
      <c>The alleged chain is not actually a chain of certificates.</c>
      <c>bad certificate</c>
      <c>One or more certificates in the chain are not valid (e.g., not properly encoded).</c>
      <c>shutdown</c>
      <c>The log has ceased operation and is not accepting new submissions.</c>
</texttable>

<t>If the version of <spanx style="verb">sct</spanx> is not v2, then a v2 client may be unable to verify the
signature. It MUST NOT construe this as an error. This is to avoid forcing an
upgrade of compliant v2 clients that do not use the returned SCTs.</t>

<t>If a log detects bad encoding in a chain that otherwise verifies correctly then
the log MUST either log the certificate or return the "bad certificate" error.
If the certificate is logged, an SCT MUST be issued. Logging the certificate is
useful, because monitors (<xref target="monitor"/>) can then detect these encoding errors,
which may be accepted by some TLS clients.</t>

</section>
<section anchor="add-pre-chain" title="Add PreCertChain to Log">

<t>POST https://&lt;log server&gt;/ct/v2/add-pre-chain</t>

<t><list style="hanging">
  <t hangText='Inputs:'>
        <list style="hanging">
        <t hangText='precertificate:'>
        The base64 encoded precertificate.</t>
        <t hangText='chain:'>
        An array of base64 encoded CA certificates. The first element is the signer
of the precertificate; the second certifies the first and so on to the last,
which either is, or is certified by, an accepted trust anchor.</t>
      </list>
  </t>
  <t hangText='Outputs:'>
        <list style="hanging">
        <t hangText='sct:'>
        A base64 encoded <spanx style="verb">TransItem</spanx> of type <spanx style="verb">precert_sct_v2</spanx>, signed by this log,
that corresponds to the submitted precertificate.</t>
      </list>
  </t>
</list></t>

<t>Errors are the same as in <xref target="add-chain"/>.</t>

</section>
<section anchor="get-sth" title="Retrieve Latest Signed Tree Head">

<t>GET https://&lt;log server&gt;/ct/v2/get-sth</t>

<t>No inputs.</t>

<t><list style="hanging">
  <t hangText='Outputs:'>
        <list style="hanging">
        <t hangText='sth:'>
        A base64 encoded <spanx style="verb">TransItem</spanx> of type <spanx style="verb">signed_tree_head_v2</spanx>, signed by this
log, that is no older than the log's MMD.</t>
      </list>
  </t>
</list></t>

</section>
<section anchor="get-sth-consistency" title="Retrieve Merkle Consistency Proof between Two Signed Tree Heads">

<t>GET https://&lt;log server&gt;/ct/v2/get-sth-consistency</t>

<t><list style="hanging">
  <t hangText='Inputs:'>
        <list style="hanging">
        <t hangText='first:'>
        The tree_size of the older tree, in decimal.</t>
        <t hangText='second:'>
        The tree_size of the newer tree, in decimal (optional).</t>
      </list>
  </t>
</list></t>

<t><list style='empty'>
  <t>Both tree sizes must be from existing v2 STHs. However, because of skew, the
receiving front-end may not know one or both of the existing STHs. If both are
known, then only the <spanx style="verb">consistency</spanx> output is returned. If the first is known
but the second is not (or has been omitted), then the latest known STH is
returned, along with a consistency proof between the first STH and the latest.
If neither are known, then the latest known STH is returned without a
consistency proof.</t>
</list></t>

<t><list style="hanging">
  <t hangText='Outputs:'>
        <list style="hanging">
        <t hangText='consistency:'>
        A base64 encoded <spanx style="verb">TransItem</spanx> of type <spanx style="verb">consistency_proof_v2</spanx>, whose
<spanx style="verb">tree_size_1</spanx> MUST match the <spanx style="verb">first</spanx> input. If the <spanx style="verb">sth</spanx> output is omitted,
then <spanx style="verb">tree_size_2</spanx> MUST match the <spanx style="verb">second</spanx> input.</t>
        <t hangText='sth:'>
        A base64 encoded <spanx style="verb">TransItem</spanx> of type <spanx style="verb">signed_tree_head_v2</spanx>, signed by this
log.</t>
      </list>
  </t>
</list></t>

<t><list style='empty'>
  <t>Note that no signature is required for the <spanx style="verb">consistency</spanx> output as it is used
to verify the consistency between two STHs, which are signed.</t>
</list></t>

<t>Error codes:</t>

<texttable>
      <ttcol align='left'>Error Code</ttcol>
      <ttcol align='left'>Meaning</ttcol>
      <c>first unknown</c>
      <c><spanx style="verb">first</spanx> is before the latest known STH but is not from an existing STH.</c>
      <c>second unknown</c>
      <c><spanx style="verb">second</spanx> is before the latest known STH but is not from an existing STH.</c>
</texttable>

<t>See <xref target="verify_consistency"/> for an outline of how to use the <spanx style="verb">consistency</spanx>
output.</t>

</section>
<section anchor="get-proof-by-hash" title="Retrieve Merkle Inclusion Proof from Log by Leaf Hash">

<t>GET https://&lt;log server&gt;/ct/v2/get-proof-by-hash</t>

<t><list style="hanging">
  <t hangText='Inputs:'>
        <list style="hanging">
        <t hangText='hash:'>
        A base64 encoded v2 leaf hash.</t>
        <t hangText='tree_size:'>
        The tree_size of the tree on which to base the proof, in decimal.</t>
      </list>
  </t>
</list></t>

<t><list style='empty'>
  <t>The <spanx style="verb">hash</spanx> must be calculated as defined in <xref target="tree_leaves"/>. The <spanx style="verb">tree_size</spanx>
must designate an existing v2 STH. Because of skew, the front-end may not know
the requested STH. In that case, it will return the latest STH it knows, along
with an inclusion proof to that STH. If the front-end knows the requested STH
then only <spanx style="verb">inclusion</spanx> is returned.</t>
</list></t>

<t><list style="hanging">
  <t hangText='Outputs:'>
        <list style="hanging">
        <t hangText='inclusion:'>
        A base64 encoded <spanx style="verb">TransItem</spanx> of type <spanx style="verb">inclusion_proof_v2</spanx> whose
<spanx style="verb">inclusion_path</spanx> array of Merkle Tree nodes proves the inclusion of the
chosen certificate in the selected STH.</t>
        <t hangText='sth:'>
        A base64 encoded <spanx style="verb">TransItem</spanx> of type <spanx style="verb">signed_tree_head_v2</spanx>, signed by this
log.</t>
      </list>
  </t>
</list></t>

<t><list style='empty'>
  <t>Note that no signature is required for the <spanx style="verb">inclusion</spanx> output as it is used to
verify inclusion in the selected STH, which is signed.</t>
</list></t>

<t>Error codes:</t>

<texttable>
      <ttcol align='left'>Error Code</ttcol>
      <ttcol align='left'>Meaning</ttcol>
      <c>hash unknown</c>
      <c><spanx style="verb">hash</spanx> is not the hash of a known leaf (may be caused by skew or by a known certificate not yet merged).</c>
      <c>tree_size unknown</c>
      <c><spanx style="verb">hash</spanx> is before the latest known STH but is not from an existing STH.</c>
</texttable>

<t>See <xref target="verify_inclusion"/> for an outline of how to use the <spanx style="verb">inclusion</spanx> output.</t>

</section>
<section anchor="get-all-by-hash" title="Retrieve Merkle Inclusion Proof, Signed Tree Head and Consistency Proof by Leaf Hash">

<t>GET https://&lt;log server&gt;/ct/v2/get-all-by-hash</t>

<t><list style="hanging">
  <t hangText='Inputs:'>
        <list style="hanging">
        <t hangText='hash:'>
        A base64 encoded v2 leaf hash.</t>
        <t hangText='tree_size:'>
        The tree_size of the tree on which to base the proofs, in decimal.</t>
      </list>
  </t>
</list></t>

<t><list style='empty'>
  <t>The <spanx style="verb">hash</spanx> must be calculated as defined in <xref target="tree_leaves"/>. The <spanx style="verb">tree_size</spanx>
must designate an existing v2 STH.</t>
</list></t>

<t><list style='empty'>
  <t>Because of skew, the front-end may not know the requested STH or the requested
hash, which leads to a number of cases.</t>
</list></t>

<t><list style='empty'>
  <t><list style="hanging">
    <t hangText='latest STH &lt; requested STH'>
    Return latest STH.</t>
  </list></t>
</list></t>

<t><list style='empty'>
  <t><list style="hanging">
    <t hangText='latest STH &gt; requested STH'>
    Return latest STH and a consistency proof between it and the requested STH
(see <xref target="get-sth-consistency"/>).</t>
  </list></t>
</list></t>

<t><list style='empty'>
  <t><list style="hanging">
    <t hangText='index of requested hash &lt; latest STH'>
    Return <spanx style="verb">inclusion</spanx>.</t>
  </list></t>
</list></t>

<t><list style='empty'>
  <t>Note that more than one case can be true, in which case the returned data is
their concatenation. It is also possible for none to be true, in which case
the front-end MUST return an empty response.</t>
</list></t>

<t><list style="hanging">
  <t hangText='Outputs:'>
        <list style="hanging">
        <t hangText='inclusion:'>
        A base64 encoded <spanx style="verb">TransItem</spanx> of type <spanx style="verb">inclusion_proof_v2</spanx> whose
<spanx style="verb">inclusion_path</spanx> array of Merkle Tree nodes proves the inclusion of the
chosen certificate in the returned STH.</t>
        <t hangText='sth:'>
        A base64 encoded <spanx style="verb">TransItem</spanx> of type <spanx style="verb">signed_tree_head_v2</spanx>, signed by this
log.</t>
        <t hangText='consistency:'>
        A base64 encoded <spanx style="verb">TransItem</spanx> of type <spanx style="verb">consistency_proof_v2</spanx> that proves the
consistency of the requested STH and the returned STH.</t>
      </list>
  </t>
</list></t>

<t><list style='empty'>
  <t>Note that no signature is required for the <spanx style="verb">inclusion</spanx> or <spanx style="verb">consistency</spanx>
outputs as they are used to verify inclusion in and consistency of STHs, which
are signed.</t>
</list></t>

<t>Errors are the same as in <xref target="get-proof-by-hash"/>.</t>

<t>See <xref target="verify_inclusion"/> for an outline of how to use the <spanx style="verb">inclusion</spanx> output,
and see <xref target="verify_consistency"/> for an outline of how to use the <spanx style="verb">consistency</spanx>
output.</t>

</section>
<section anchor="get-entries" title="Retrieve Entries and STH from Log">

<t>GET https://&lt;log server&gt;/ct/v2/get-entries</t>

<t><list style="hanging">
  <t hangText='Inputs:'>
        <list style="hanging">
        <t hangText='start:'>
        0-based index of first entry to retrieve, in decimal.</t>
        <t hangText='end:'>
        0-based index of last entry to retrieve, in decimal.</t>
      </list>
  </t>
  <t hangText='Outputs:'>
        <list style="hanging">
        <t hangText='entries:'>
        An array of objects, each consisting of

            <list style="hanging">
              <t hangText='leaf_input:'>
              The base64 encoded <spanx style="verb">TransItem</spanx> structure of type <spanx style="verb">x509_entry_v2</spanx> or
<spanx style="verb">precert_entry_v2</spanx> (see <xref target="tree_leaves"/>).</t>
              <t hangText='log_entry:'>
              The base64 encoded log entry (see <xref target="log_entries"/>). In the case of an
<spanx style="verb">x509_entry_v2</spanx> entry, this is the whole <spanx style="verb">X509ChainEntry</spanx>; and in the case
of a <spanx style="verb">precert_entry_v2</spanx>, this is the whole <spanx style="verb">PrecertChainEntryV2</spanx>.</t>
              <t hangText='sct:'>
              The base64 encoded <spanx style="verb">TransItem</spanx> of type <spanx style="verb">x509_sct_v2</spanx> or <spanx style="verb">precert_sct_v2</spanx>
corresponding to this log entry.</t>
            </list>
        </t>
        <t hangText='sth:'>
        A base64 encoded <spanx style="verb">TransItem</spanx> of type <spanx style="verb">signed_tree_head_v2</spanx>, signed by this
log.</t>
      </list>
  </t>
</list></t>

<t>Note that this message is not signed -- the <spanx style="verb">entries</spanx> data can be verified by
constructing the Merkle Tree Hash corresponding to a retrieved STH. All leaves
MUST be v2. However, a compliant v2 client MUST NOT construe an unrecognized
TransItem type as an error. This means it may be unable to parse some entries,
but note that each client can inspect the entries it does recognize as well as
verify the integrity of the data by treating unrecognized leaves as opaque input
to the tree.</t>

<t>The <spanx style="verb">start</spanx> and <spanx style="verb">end</spanx> parameters SHOULD be within the range 0 &lt;= x &lt; <spanx style="verb">tree_size</spanx>
as returned by <spanx style="verb">get-sth</spanx> in <xref target="get-sth"/>.</t>

<t>The <spanx style="verb">start</spanx> parameter MUST be less than or equal to the <spanx style="verb">end</spanx> parameter.</t>

<t>Log servers MUST honor requests where 0 &lt;= <spanx style="verb">start</spanx> &lt; <spanx style="verb">tree_size</spanx> and <spanx style="verb">end</spanx> &gt;=
<spanx style="verb">tree_size</spanx> by returning a partial response covering only the valid entries in
the specified range. <spanx style="verb">end</spanx> &gt;= <spanx style="verb">tree_size</spanx> could be caused by skew. Note that the
following restriction may also apply:</t>

<t>Logs MAY restrict the number of entries that can be retrieved per <spanx style="verb">get-entries</spanx>
request. If a client requests more than the permitted number of entries, the log
SHALL return the maximum number of entries permissible. These entries SHALL be
sequential beginning with the entry specified by <spanx style="verb">start</spanx>.</t>

<t>Because of skew, it is possible the log server will not have any entries between
<spanx style="verb">start</spanx> and <spanx style="verb">end</spanx>. In this case it MUST return an empty <spanx style="verb">entries</spanx> array.</t>

<t>In any case, the log server MUST return the latest STH it knows about.</t>

<t>See <xref target="verify_hash"/> for an outline of how to use a complete list of <spanx style="verb">leaf_input</spanx>
entries to verify the <spanx style="verb">root_hash</spanx>.</t>

</section>
<section anchor="get-anchors" title="Retrieve Accepted Trust Anchors">

<t>GET https://&lt;log server&gt;/ct/v2/get-anchors</t>

<t>No inputs.</t>

<t><list style="hanging">
  <t hangText='Outputs:'>
        <list style="hanging">
        <t hangText='certificates:'>
        An array of base64 encoded trust anchors that are acceptable to the log.</t>
        <t hangText='max_chain:'>
        If the server has chosen to limit the length of chains it accepts, this is
the maximum number of certificates in the chain, in decimal. If there is no
limit, this is omitted.</t>
      </list>
  </t>
</list></t>

</section>
</section>
<section anchor="optional-client-messages" title="Optional Client Messages">

<t>Logs MAY implement these messages. They are not required for correct operation
of logs or their clients, but may be convenient in some circumstances.</t>

<section anchor="get-entry-number-for-sct" title="Get Entry Number for SCT">

<t>GET https://&lt;log server&gt;/ct/v2/get-entry-for-sct</t>

<t><list style="hanging">
  <t hangText='Inputs:'>
        <list style="hanging">
        <t hangText='sct:'>
        A base64 encoded <spanx style="verb">TransItem</spanx> of type <spanx style="verb">x509_sct_v2</spanx> or <spanx style="verb">precert_sct_v2</spanx>
signed by this log.</t>
      </list>
  </t>
  <t hangText='Outputs:'>
        <list style="hanging">
        <t hangText='entry:'>
        0-based index of the log entry corresponding to the supplied SCT.</t>
      </list>
  </t>
</list></t>

<t>Error codes:</t>

<texttable>
      <ttcol align='left'>Error Code</ttcol>
      <ttcol align='left'>Meaning</ttcol>
      <c>bad signature</c>
      <c><spanx style="verb">sct</spanx> is not signed by this log.</c>
      <c>not found</c>
      <c><spanx style="verb">sct</spanx> does not correspond to an entry that is currently available.</c>
</texttable>

<t>Note that any SCT signed by a log MUST have a corresponding entry in the log,
but it may not be retrievable until the MMD has passed since the SCT was issued.</t>

</section>
<section anchor="get-entry-numbers-for-tbscertificate" title="Get Entry Numbers for TBSCertificate">

<t>GET https://&lt;log server&gt;/ct/v2/get-entry-for-tbscertificate</t>

<t><list style="hanging">
  <t hangText='Inputs:'>
        <list style="hanging">
        <t hangText='hash:'>
        A base64 encoded HASH of a <spanx style="verb">TBSCertificate</spanx> for which the log has previously
issued an SCT. (Note that a precertificate's TBSCertificate is reconstructed
from the corresponding certificate as described in
<xref target="reconstructing_tbscertificate"/>).</t>
      </list>
  </t>
  <t hangText='Outputs:'>
        <list style="hanging">
        <t hangText='entries:'>
        An array of 0-based indices of log entries corresponding to the supplied
HASH.</t>
      </list>
  </t>
</list></t>

<t>Error codes:</t>

<texttable>
      <ttcol align='left'>Error Code</ttcol>
      <ttcol align='left'>Meaning</ttcol>
      <c>bad hash</c>
      <c><spanx style="verb">hash</spanx> is not the right size or format.</c>
      <c>not found</c>
      <c><spanx style="verb">sct</spanx> does not correspond to an entry that is currently available.</c>
</texttable>

<t>Note that it is possible for a certificate to be logged more than once. If that
is the case, the log MAY return more than one entry index. If the certificate is
present in the log, then the log MUST return at least one entry index.</t>

</section>
</section>
<section anchor="tls_servers" title="TLS Servers">

<t>TLS servers MUST use at least one of the three mechanisms listed below to
present one or more SCTs from one or more logs to each TLS client during full
TLS handshakes, where each SCT corresponds to the server certificate or to a
name-constrained intermediate the server certificate chains to. TLS servers
SHOULD also present corresponding inclusion proofs and STHs (see
<xref target="sct_with_proof"/>).</t>

<t>Three mechanisms are provided because they have different tradeoffs.</t>

<t><list style="symbols">
  <t>A TLS extension (Section 7.4.1.4 of <xref target="RFC5246"></xref>) with type <spanx style="verb">transparency_info</spanx>
(see <xref target="tls_transinfo_extension"/>). This mechanism allows TLS servers to
participate in CT without the cooperation of CAs, unlike the other two
mechanisms. It also allows SCTs and inclusion proofs to be updated on the fly.</t>
  <t>An Online Certificate Status Protocol (OCSP) <xref target="RFC6960"></xref> response extension (see
<xref target="ocsp_transinfo_extension"/>), where the OCSP response is provided in the
<spanx style="verb">CertificateStatus</spanx> message, provided that the TLS client included the
<spanx style="verb">status_request</spanx> extension in the (extended) <spanx style="verb">ClientHello</spanx> (Section 8 of
<xref target="RFC6066"></xref>). This mechanism, popularly known as OCSP stapling, is already
widely (but not universally) implemented. It also allows SCTs and inclusion
proofs to be updated on the fly.</t>
  <t>An X509v3 certificate extension (see <xref target="cert_transinfo_extension"/>). This
mechanism allows the use of unmodified TLS servers, but the SCTs and inclusion
proofs cannot be updated on the fly. Since the logs from which the SCTs and
inclusion proofs originated won't necessarily be accepted by TLS clients for
the full lifetime of the certificate, there is a risk that TLS clients will
subsequently consider the certificate to be non-compliant and in need of
re-issuance.</t>
</list></t>

<t>Additionally, a TLS server which supports presenting SCTs using an OCSP response
MAY provide it when the TLS client included the <spanx style="verb">status_request_v2</spanx> extension
(<xref target="RFC6961"></xref>) in the (extended) <spanx style="verb">ClientHello</spanx>, but only in addition to at least
one of the three mechanisms listed above.</t>

<section anchor="multiple-scts" title="Multiple SCTs">

<t>TLS servers SHOULD send SCTs from multiple logs in case one or more logs are not
acceptable to the TLS client (for example, if a log has been struck off for
misbehavior, has had a key compromise, or is not known to the TLS client). For
example:</t>

<t><list style="symbols">
  <t>If a CA and a log collude, it is possible to temporarily hide misissuance from
clients. Including SCTs from different logs makes it more difficult to mount
this attack.</t>
  <t>If a log misbehaves, a consequence may be that clients cease to trust it.
Since the time an SCT may be in use can be considerable (several years is
common in current practice when embedded in a certificate), servers may wish
to reduce the probability of their certificates being rejected as a result by
including SCTs from different logs.</t>
  <t>TLS clients may have policies related to the above risks requiring servers to
present multiple SCTs. For example, at the time of writing, Chromium
<xref target="Chromium.Log.Policy"></xref> requires multiple SCTs to be presented with EV
certificates in order for the EV indicator to be shown.</t>
</list></t>

<t>To select the logs from which to obtain SCTs, a TLS server can, for example,
examine the set of logs popular TLS clients accept and recognize.</t>

</section>
<section anchor="transitemlist-structure" title="TransItemList Structure">

<t>Multiple SCTs, inclusion proofs, and indeed <spanx style="verb">TransItem</spanx> structures of any type,
are combined into a list as follows:</t>

<figure><artwork><![CDATA[
      opaque SerializedTransItem<1..2^16-1>;

      struct {
          SerializedTransItem trans_item_list<1..2^16-1>;
      } TransItemList;
]]></artwork></figure>

<t>Here, <spanx style="verb">SerializedTransItem</spanx> is an opaque byte string that contains the
serialized <spanx style="verb">TransItem</spanx> structure. This encoding ensures that TLS clients can
decode each <spanx style="verb">TransItem</spanx> individually (so, for example, if there is a version
upgrade, out-of-date clients can still parse old <spanx style="verb">TransItem</spanx> structures while
skipping over new <spanx style="verb">TransItem</spanx> structures whose versions they don't understand).</t>

</section>
<section anchor="sct_with_proof" title="Presenting SCTs, inclusion proofs and STHs">

<t>When constructing a <spanx style="verb">TransItemList</spanx> structure, a TLS server SHOULD construct and
include <spanx style="verb">TransItem</spanx> structures of type <spanx style="verb">x509_sct_with_proof_v2</spanx> (for an SCT of
type <spanx style="verb">x509_sct_v2</spanx>) or <spanx style="verb">precert_sct_with_proof_v2</spanx> (for an SCT of type
<spanx style="verb">precert_sct_v2</spanx>), both of which encapsulate a <spanx style="verb">SCTWithProofDataV2</spanx> structure:</t>

<figure><artwork><![CDATA[
    struct {
        SignedCertificateTimestampDataV2 sct;
        SignedTreeHeadDataV2 sth;
        InclusionProofDataV2 inclusion_proof;
    } SCTWithProofDataV2;
]]></artwork></figure>

<t><spanx style="verb">sct</spanx> is the encapsulated data structure from an SCT that corresponds to the
server certificate or to a name-constrained intermediate the server certificate
chains to.</t>

<t><spanx style="verb">sth</spanx> is the encapsulated data structure from an STH that was signed by the same
log as <spanx style="verb">sct</spanx>.</t>

<t><spanx style="verb">inclusion_proof</spanx> is the encapsulated data structure from an inclusion proof
that corresponds to <spanx style="verb">sct</spanx> and can be used to compute the root in <spanx style="verb">sth</spanx>.</t>

</section>
<section anchor="presenting-scts-only" title="Presenting SCTs only">

<t>Presenting inclusion proofs and STHs in the TLS handshake helps to protect the
client's privacy (see <xref target="validating_inclusion_proofs"/>) and reduces load on log
servers. However, if a TLS server is unable to obtain an inclusion proof and STH
that correspond to an SCT, then it MUST include <spanx style="verb">TransItem</spanx> structures of type
<spanx style="verb">x509_sct_v2</spanx> or <spanx style="verb">precert_sct_v2</spanx> in the <spanx style="verb">TransItemList</spanx>.</t>

</section>
<section anchor="tls_transinfo_extension" title="transparency_info TLS Extension">

<t>Provided that a TLS client includes the <spanx style="verb">transparency_info</spanx> extension type in
the ClientHello, the TLS server SHOULD include the <spanx style="verb">transparency_info</spanx> extension
in the ServerHello with <spanx style="verb">extension_data</spanx> set to a <spanx style="verb">TransItemList</spanx>. The TLS
server SHOULD ignore any <spanx style="verb">extension_data</spanx> sent by the TLS client. Additionally,
the TLS server MUST NOT process or include this extension when a TLS session is
resumed, since session resumption uses the original session information.</t>

</section>
<section anchor="cachedinfo-tls-extension" title="cached_info TLS Extension">

<t>When a TLS server includes the <spanx style="verb">transparency_info</spanx> extension in the ServerHello,
it SHOULD NOT include any <spanx style="verb">TransItem</spanx> structures of type
<spanx style="verb">x509_sct_with_proof_v2</spanx>, <spanx style="verb">x509_sct_v2</spanx>, <spanx style="verb">precert_sct_with_proof_v2</spanx> or
<spanx style="verb">precert_sct_v2</spanx> in the <spanx style="verb">TransItemList</spanx> if all of the following conditions are
met:</t>

<t><list style="symbols">
  <t>The TLS client includes the <spanx style="verb">transparency_info</spanx> extension type in the
ClientHello.</t>
  <t>The TLS client includes the <spanx style="verb">cached_info</spanx> (<xref target="RFC7924"></xref>) extension type in the
ClientHello, with a <spanx style="verb">CachedObject</spanx> of type <spanx style="verb">ct_compliant</spanx> (see
<xref target="tls_cachedinfo_extension"/>) and at least one <spanx style="verb">CachedObject</spanx> of type <spanx style="verb">cert</spanx>.</t>
  <t>The TLS server sends a modified Certificate message (as described in section
4.1 of <xref target="RFC7924"></xref>).</t>
</list></t>

<t>TLS servers SHOULD ignore the <spanx style="verb">hash_value</spanx> fields of each <spanx style="verb">CachedObject</spanx> of type
<spanx style="verb">ct_compliant</spanx> sent by TLS clients.</t>

</section>
</section>
<section anchor="certification-authorities" title="Certification Authorities">

<section anchor="x509v3_transinfo_extension" title="Transparency Information X.509v3 Extension">

<t>The Transparency Information X.509v3 extension, which has OID 1.3.101.75 and
SHOULD be non-critical, contains one or more <spanx style="verb">TransItem</spanx> structures in a
<spanx style="verb">TransItemList</spanx>. This extension MAY be included in OCSP responses (see
<xref target="ocsp_transinfo_extension"/>) and certificates (see
<xref target="cert_transinfo_extension"/>). Since RFC5280 requires the <spanx style="verb">extnValue</spanx> field (an
OCTET STRING) of each X.509v3 extension to include the DER encoding of an ASN.1
value, a <spanx style="verb">TransItemList</spanx> MUST NOT be included directly. Instead, it MUST be
wrapped inside an additional OCTET STRING, which is then put into the
<spanx style="verb">extnValue</spanx> field:</t>

<figure><artwork><![CDATA[
    TransparencyInformationSyntax ::= OCTET STRING
]]></artwork></figure>

<t><spanx style="verb">TransparencyInformationSyntax</spanx> contains a <spanx style="verb">TransItemList</spanx>.</t>

<section anchor="ocsp_transinfo_extension" title="OCSP Response Extension">

<t>A certification authority MAY include a Transparency Information X.509v3
extension in the <spanx style="verb">singleExtensions</spanx> of a <spanx style="verb">SingleResponse</spanx> in an OCSP response.
The included SCTs or inclusion proofs MUST be for the certificate identified by
the <spanx style="verb">certID</spanx> of that <spanx style="verb">SingleResponse</spanx>, or for a precertificate that corresponds
to that certificate, or for a name-constrained intermediate to which that
certificate chains.</t>

</section>
<section anchor="cert_transinfo_extension" title="Certificate Extension">

<t>A certification authority MAY include a Transparency Information X.509v3
extension in a certificate. Any included SCTs or inclusion proofs MUST be either
for a precertificate that corresponds to this certificate, or for a
name-constrained intermediate to which this certificate chains.</t>

</section>
</section>
<section anchor="tls_feature_extension" title="TLS Feature Extension">

<t>A certification authority MAY include the transparency_info
(<xref target="tls_transinfo_extension"/>) TLS extension identifier in the TLS Feature
<xref target="RFC7633"></xref> certificate extension in root, intermediate and end-entity
certificates. When a certificate chain includes such a certificate, this
indicates that CT compliance is required.</t>

</section>
</section>
<section anchor="clients" title="Clients">

<t>There are various different functions clients of logs might perform. We describe
here some typical clients and how they should function. Any inconsistency may be
used as evidence that a log has not behaved correctly, and the signatures on the
data structures prevent the log from denying that misbehavior.</t>

<t>All clients need various metadata in order to communicate with logs and verify
their responses. This metadata is described below, but note that this document
does not describe how the metadata is obtained, which is implementation
dependent (see, for example, <xref target="Chromium.Policy"></xref>).</t>

<t>Clients should somehow exchange STHs they see, or make them available for
scrutiny, in order to ensure that they all have a consistent view. The exact
mechanisms will be in separate documents, but it is expected there will be a
variety.</t>

<section anchor="metadata" title="Metadata">

<t>In order to communicate with and verify a log, clients need metadata about the
log.</t>

<t><list style="hanging">
  <t hangText='Base URL:'>
  The URL to substitute for &lt;log server&gt; in <xref target="client_messages"/>.</t>
  <t hangText='Hash Algorithm:'>
  The hash algorithm used for the Merkle Tree (see <xref target="hash_algorithms"/>).</t>
  <t hangText='Signing Algorithm:'>
  The signing algorithm used (see <xref target="signatures"/>).</t>
  <t hangText='Public Key:'>
  The public key used to verify signatures generated by the log. A log MUST NOT
use the same keypair as any other log.</t>
  <t hangText='Log ID:'>
  The OID that uniquely identifies the log.</t>
  <t hangText='Maximum Merge Delay:'>
  The MMD the log has committed to.</t>
  <t hangText='Version:'>
  The version of the protocol supported by the log (currently 1 or 2).</t>
  <t hangText='Maximum Chain Length:'>
  The longest chain submission the log is willing to accept, if the log chose to
limit it.</t>
  <t hangText='STH Frequency Count:'>
  The maximum number of STHs the log may produce in any period equal to the
<spanx style="verb">Maximum Merge Delay</spanx> (see <xref target="STH"/>).</t>
  <t hangText='Final STH:'>
  If a log has been closed down (i.e., no longer accepts new entries), existing
entries may still be valid. In this case, the client should know the final
valid STH in the log to ensure no new entries can be added without detection.
The final STH should be provided in the form of a TransItem of type
<spanx style="verb">signed_tree_head_v2</spanx>.</t>
</list></t>

<t><xref target="JSON.Metadata"></xref> is an example of a metadata format which includes the above
elements.</t>

</section>
<section anchor="tls_clients" title="TLS Client">

<section anchor="receiving-scts" title="Receiving SCTs">

<t>TLS clients receive SCTs alongside or in certificates. TLS clients MUST
implement all of the three mechanisms by which TLS servers may present SCTs (see
<xref target="tls_servers"/>). TLS clients MAY also accept SCTs via the <spanx style="verb">status_request_v2</spanx>
extension (<xref target="RFC6961"></xref>). TLS clients that support the <spanx style="verb">transparency_info</spanx> TLS
extension SHOULD include it in ClientHello messages, with empty
<spanx style="verb">extension_data</spanx>. TLS clients may also receive inclusion proofs in addition to
SCTs, which should be checked once the SCTs are validated.</t>

</section>
<section anchor="reconstructing_tbscertificate" title="Reconstructing the TBSCertificate">

<t>To reconstruct the TBSCertificate component of a precertificate from a
certificate, TLS clients should remove the Transparency Information extension
described in <xref target="x509v3_transinfo_extension"/>.</t>

<t>If the SCT checked is for a Precertificate (where the <spanx style="verb">type</spanx> of the <spanx style="verb">TransItem</spanx>
is <spanx style="verb">precert_sct_v2</spanx>), then the client SHOULD also remove embedded v1 SCTs,
identified by OID 1.3.6.1.4.1.11129.2.4.2 (See Section 3.3. of <xref target="RFC6962"></xref>), in
the process of reconstructing the TBSCertificate. That is to allow embedded v1
and v2 SCTs to co-exist in a certificate (See <xref target="v1_coexistence"/>).</t>

</section>
<section anchor="validating-scts" title="Validating SCTs">

<t>In addition to normal validation of the server certificate and its chain, TLS
clients SHOULD validate each received SCT for which they have the corresponding
log's metadata. To validate an SCT, a TLS client computes the signature input
from the SCT data and the corresponding certificate, and then verifies the
signature using the corresponding log's public key. TLS clients MUST NOT
consider valid any SCT whose timestamp is in the future.</t>

<t>Before considering any SCT to be invalid, the TLS client MUST attempt to
validate it against the server certificate and against each of the zero or more
suitable name-constrained intermediates (<xref target="name_constrained"/>) in the chain.
These certificates may be evaluated in the order they appear in the chain, or,
indeed, in any order.</t>

</section>
<section anchor="validating_inclusion_proofs" title="Validating inclusion proofs">

<t>After validating a received SCT, a TLS client MAY request a corresponding
inclusion proof (if one is not already available) and then verify it. An
inclusion proof can be requested directly from a log using <spanx style="verb">get-proof-by-hash</spanx>
(<xref target="get-proof-by-hash"/>) or <spanx style="verb">get-all-by-hash</spanx> (<xref target="get-all-by-hash"/>), but note
that this will disclose to the log which TLS server the client has been
communicating with.</t>

<t>Alternatively, if the TLS client has received an inclusion proof (and an STH)
alongside the SCT, it can proceed to verifying the inclusion proof to the
provided STH. The client then has to verify consistency between the provided STH
and an STH it knows about, which is less sensitive from a privacy perspective.</t>

<t>TLS clients SHOULD also verify each received inclusion proof (see
<xref target="verify_inclusion"/>) for which they have the corresponding log's metadata, to
audit the log and gain confidence that the certificate is logged.</t>

<t>If the TLS client holds an STH that predates the SCT, it MAY, in the process of
auditing, request a new STH from the log (<xref target="get-sth"/>), then verify it by
requesting a consistency proof (<xref target="get-sth-consistency"/>). Note that if the TLS
client uses <spanx style="verb">get-all-by-hash</spanx>, then it will already have the new STH.</t>

</section>
<section anchor="evaluating-compliance" title="Evaluating compliance">

<t>To be considered compliant, a certificate MUST be accompanied by at least one
valid SCT. A certificate not accompanied by any valid SCTs MUST NOT be
considered compliant by TLS clients.</t>

<t>A TLS client MUST NOT evaluate compliance if it did not send both the
<spanx style="verb">transparency_info</spanx> and <spanx style="verb">status_request</spanx> TLS extensions in the ClientHello.</t>

</section>
<section anchor="tls-feature-extension" title="TLS Feature Extension">

<t>If any certificate in a chain includes the transparency_info
(<xref target="tls_transinfo_extension"/>) TLS extension identifier in the TLS Feature
<xref target="RFC7633"></xref> certificate extension, then CT compliance (using any of the mechanisms
from <xref target="tls_servers"/>) is required.</t>

</section>
<section anchor="tls_cachedinfo_extension" title="cached_info TLS Extension">

<t>If a TLS client uses the <spanx style="verb">cached_info</spanx> TLS extension (<xref target="RFC7924"></xref>) to indicate 1
or more cached certificates, all of which it already considers to be CT
compliant, the TLS client MAY also include a <spanx style="verb">CachedObject</spanx> of type
<spanx style="verb">ct_compliant</spanx> in the <spanx style="verb">cached_info</spanx> extension. The <spanx style="verb">hash_value</spanx> field MUST be 1
byte long with the value 0.</t>

</section>
<section anchor="handling-of-non-compliance" title="Handling of Non-compliance">

<t>If a TLS server presents a certificate chain that is non-compliant, and the use
of a compliant certificate is mandated by an explicit security policy,
application protocol specification, the TLS Feature extension or any other
means, the TLS client MUST refuse the connection.</t>

</section>
</section>
<section anchor="monitor" title="Monitor">

<t>Monitors watch logs to check that they behave correctly, for certificates of
interest, or both. For example, a monitor may be configured to report on all
certificates that apply to a specific domain name when fetching new entries for
consistency validation.</t>

<t>A monitor needs to, at least, inspect every new entry in each log it watches.
It may also want to keep copies of entire logs. In order to do this, it should
follow these steps for each log:</t>

<t><list style="numbers">
  <t>Fetch the current STH (<xref target="get-sth"/>).</t>
  <t>Verify the STH signature.</t>
  <t>Fetch all the entries in the tree corresponding to the STH
(<xref target="get-entries"/>).</t>
  <t>Confirm that the tree made from the fetched entries produces the same hash as
that in the STH.</t>
  <t>Fetch the current STH (<xref target="get-sth"/>). Repeat until the STH changes.</t>
  <t>Verify the STH signature.</t>
  <t>Fetch all the new entries in the tree corresponding to the STH
(<xref target="get-entries"/>). If they remain unavailable for an extended period, then
this should be viewed as misbehavior on the part of the log.</t>
  <t>Either:  <list style="numbers">
      <t>Verify that the updated list of all entries generates a tree with the
same hash as the new STH.</t>
    </list>
Or, if it is not keeping all log entries:  <list style="numbers">
      <t>Fetch a consistency proof for the new STH with the previous STH
(<xref target="get-sth-consistency"/>).</t>
      <t>Verify the consistency proof.</t>
      <t>Verify that the new entries generate the corresponding elements in the
consistency proof.</t>
    </list></t>
  <t>Go to Step 5.</t>
</list></t>

</section>
<section anchor="auditing" title="Auditing">

<t>Auditing ensures that the current published state of a log is reachable from
previously published states that are known to be good, and that the promises
made by the log in the form of SCTs have been kept. Audits are performed by
monitors or TLS clients.</t>

<t>In particular, there are four log behaviour properties that should be checked:</t>

<t><list style="symbols">
  <t>The Maximum Merge Delay (MMD).</t>
  <t>The STH Frequency Count.</t>
  <t>The append-only property.</t>
  <t>The consistency of the log view presented to all query sources.</t>
</list></t>

<t>A benign, conformant log publishes a series of STHs over time, each derived from
the previous STH and the submitted entries incorporated into the log since
publication of the previous STH. This can be proven through auditing of STHs.
SCTs returned to TLS clients can be audited by verifying against the
accompanying certificate, and using Merkle Inclusion Proofs, against the log's
Merkle tree.</t>

<t>The action taken by the auditor if an audit fails is not specified, but note
that in general if audit fails, the auditor is in possession of signed proof of
the log's misbehavior.</t>

<t>A monitor (<xref target="monitor"/>) can audit by verifying the consistency of STHs it
receives, ensure that each entry can be fetched and that the STH is indeed the
result of making a tree from all fetched entries.</t>

<t>A TLS client (<xref target="tls_clients"/>) can audit by verifying an SCT against any STH
dated after the SCT timestamp + the Maximum Merge Delay by requesting a Merkle
inclusion proof (<xref target="get-proof-by-hash"/>). It can also verify that the SCT
corresponds to the certificate it arrived with (i.e., the log entry is that
certificate, is a precertificate for that certificate or is an appropriate
name-constrained intermediate (<xref target="name_constrained"/>).</t>

<t>Checking of the consistency of the log view presented to all entities is more
difficult to perform because it requires a way to share log responses among a
set of CT-aware entities, and is discussed in <xref target="misbehaving_logs"/>.</t>

<t>The following algorithm outlines may be useful for clients that wish to perform
various audit operations.</t>

<section anchor="verify_inclusion" title="Verifying an inclusion proof">

<t>When a client has received a <spanx style="verb">TransItem</spanx> of type <spanx style="verb">inclusion_proof_v2</spanx> and wishes
to verify inclusion of an input <spanx style="verb">hash</spanx> for an STH with a given <spanx style="verb">tree_size</spanx> and
<spanx style="verb">root_hash</spanx>, the following algorithm may be used to prove the <spanx style="verb">hash</spanx> was
included in the <spanx style="verb">root_hash</spanx>:</t>

<t><list style="numbers">
  <t>Compare <spanx style="verb">leaf_index</spanx> against <spanx style="verb">tree_size</spanx>. If <spanx style="verb">leaf_index</spanx> is greater than or
equal to <spanx style="verb">tree_size</spanx> fail the proof verification.</t>
  <t>Set <spanx style="verb">fn</spanx> to <spanx style="verb">leaf_index</spanx> and <spanx style="verb">sn</spanx> to <spanx style="verb">tree_size - 1</spanx>.</t>
  <t>Set <spanx style="verb">r</spanx> to <spanx style="verb">hash</spanx>.</t>
  <t>For each value <spanx style="verb">p</spanx> in the <spanx style="verb">inclusion_path</spanx> array:  <vspace blankLines='1'/>
If <spanx style="verb">sn</spanx> is 0, stop the iteration and fail the proof verification.  <vspace blankLines='1'/>
If <spanx style="verb">LSB(fn)</spanx> is set, or if <spanx style="verb">fn</spanx> is equal to <spanx style="verb">sn</spanx>, then:  <list style="numbers">
      <t>Set <spanx style="verb">r</spanx> to <spanx style="verb">HASH(0x01 || p || r)</spanx></t>
      <t>If <spanx style="verb">LSB(fn)</spanx> is not set, then right-shift both <spanx style="verb">fn</spanx> and <spanx style="verb">sn</spanx> equally
until either <spanx style="verb">LSB(fn)</spanx> is set or <spanx style="verb">fn</spanx> is <spanx style="verb">0</spanx>.</t>
    </list>
Otherwise:  <list style="numbers">
      <t>Set <spanx style="verb">r</spanx> to <spanx style="verb">HASH(0x01 || r || p)</spanx></t>
    </list>
Finally, right-shift both <spanx style="verb">fn</spanx> and <spanx style="verb">sn</spanx> one time.</t>
  <t>Compare <spanx style="verb">sn</spanx> to 0. Compare <spanx style="verb">r</spanx> against the <spanx style="verb">root_hash</spanx>. If <spanx style="verb">sn</spanx> is equal to
0, and <spanx style="verb">r</spanx> and the <spanx style="verb">root_hash</spanx> are equal, then the log has proven the
inclusion of <spanx style="verb">hash</spanx>. Otherwise, fail the proof verification.</t>
</list></t>

</section>
<section anchor="verify_consistency" title="Verifying consistency between two STHs">

<t>When a client has an STH <spanx style="verb">first_hash</spanx> for tree size <spanx style="verb">first</spanx>, an STH
<spanx style="verb">second_hash</spanx> for tree size <spanx style="verb">second</spanx> where <spanx style="verb">0 &lt; first &lt; second</spanx>, and has
received a <spanx style="verb">TransItem</spanx> of type <spanx style="verb">consistency_proof_v2</spanx> that they wish to use to
verify both hashes, the following algorithm may be used:</t>

<t><list style="numbers">
  <t>If <spanx style="verb">first</spanx> is an exact power of 2, then prepend <spanx style="verb">first_hash</spanx> to the
<spanx style="verb">consistency_path</spanx> array.</t>
  <t>Set <spanx style="verb">fn</spanx> to <spanx style="verb">first - 1</spanx> and <spanx style="verb">sn</spanx> to <spanx style="verb">second - 1</spanx>.</t>
  <t>If <spanx style="verb">LSB(fn)</spanx> is set, then right-shift both <spanx style="verb">fn</spanx> and <spanx style="verb">sn</spanx> equally until
<spanx style="verb">LSB(fn)</spanx> is not set.</t>
  <t>Set both <spanx style="verb">fr</spanx> and <spanx style="verb">sr</spanx> to the first value in the <spanx style="verb">consistency_path</spanx> array.</t>
  <t>For each subsequent value <spanx style="verb">c</spanx> in the <spanx style="verb">consistency_path</spanx> array:  <vspace blankLines='1'/>
If <spanx style="verb">sn</spanx> is 0, stop the iteration and fail the proof verification.  <vspace blankLines='1'/>
If <spanx style="verb">LSB(fn)</spanx> is set, or if <spanx style="verb">fn</spanx> is equal to <spanx style="verb">sn</spanx>, then:  <list style="numbers">
      <t>Set <spanx style="verb">fr</spanx> to <spanx style="verb">HASH(0x01 || c || fr)</spanx><vspace />
Set <spanx style="verb">sr</spanx> to <spanx style="verb">HASH(0x01 || c || sr)</spanx></t>
      <t>If <spanx style="verb">LSB(fn)</spanx> is not set, then right-shift both <spanx style="verb">fn</spanx> and <spanx style="verb">sn</spanx> equally
until either <spanx style="verb">LSB(fn)</spanx> is set or <spanx style="verb">fn</spanx> is <spanx style="verb">0</spanx>.</t>
    </list>
Otherwise:  <list style="numbers">
      <t>Set <spanx style="verb">sr</spanx> to <spanx style="verb">HASH(0x01 || sr || c)</spanx></t>
    </list>
Finally, right-shift both <spanx style="verb">fn</spanx> and <spanx style="verb">sn</spanx> one time.</t>
  <t>After completing iterating through the <spanx style="verb">consistency_path</spanx> array as described
above, verify that the <spanx style="verb">fr</spanx> calculated is equal to the <spanx style="verb">first_hash</spanx> supplied,
that the <spanx style="verb">sr</spanx> calculated is equal to the <spanx style="verb">second_hash</spanx> supplied and that <spanx style="verb">sn</spanx>
is 0.</t>
</list></t>

</section>
<section anchor="verify_hash" title="Verifying root hash given entries">

<t>When a client has a complete list of leaf input <spanx style="verb">entries</spanx> from <spanx style="verb">0</spanx> up to
<spanx style="verb">tree_size - 1</spanx> and wishes to verify this list against an STH <spanx style="verb">root_hash</spanx>
returned by the log for the same <spanx style="verb">tree_size</spanx>, the following algorithm may be
used:</t>

<t><list style="numbers">
  <t>Set <spanx style="verb">stack</spanx> to an empty stack.</t>
  <t>For each <spanx style="verb">i</spanx> from <spanx style="verb">0</spanx> up to <spanx style="verb">tree_size - 1</spanx>:  <list style="numbers">
      <t>Push <spanx style="verb">HASH(0x00 || entries[i])</spanx> to <spanx style="verb">stack</spanx>.</t>
      <t>Set <spanx style="verb">merge_count</spanx> to the lowest value (<spanx style="verb">0</spanx> included) such that <spanx style="verb">LSB(i &gt;&gt;
merge_count)</spanx> is not set. In other words, set <spanx style="verb">merge_count</spanx> to the number
of consecutive <spanx style="verb">1</spanx>s found starting at the least significant bit of <spanx style="verb">i</spanx>.</t>
      <t>Repeat <spanx style="verb">merge_count</spanx> times:      <list style="numbers">
          <t>Pop <spanx style="verb">right</spanx> from <spanx style="verb">stack</spanx>.</t>
          <t>Pop <spanx style="verb">left</spanx> from <spanx style="verb">stack</spanx>.</t>
          <t>Push <spanx style="verb">HASH(0x01 || left || right)</spanx> to <spanx style="verb">stack</spanx>.</t>
        </list></t>
    </list></t>
  <t>If there is more than one element in the <spanx style="verb">stack</spanx>, repeat the same merge
procedure (Step 2.3 above) until only a single element remains.</t>
  <t>The remaining element in <spanx style="verb">stack</spanx> is the Merkle Tree hash for the given
<spanx style="verb">tree_size</spanx> and should be compared by equality against the supplied
<spanx style="verb">root_hash</spanx>.</t>
</list></t>

</section>
</section>
</section>
<section anchor="algorithm-agility" title="Algorithm Agility">

<t>It is not possible for a log to change any of its algorithms part way through
its lifetime:</t>

<t><list style="hanging">
  <t hangText='Signature algorithm:'>
  SCT signatures must remain valid so signature algorithms can only be added,
not removed.</t>
  <t hangText='Hash algorithm:'>
  A log would have to support the old and new hash algorithms to allow
backwards-compatibility with clients that are not aware of a hash algorithm
change.</t>
</list></t>

<t>Allowing multiple signature or hash algorithms for a log would require that all
data structures support it and would significantly complicate client
implementation, which is why it is not supported by this document.</t>

<t>If it should become necessary to deprecate an algorithm used by a live log, then
the log should be frozen as specified in <xref target="metadata"/> and a new log should be
started. Certificates in the frozen log that have not yet expired and require
new SCTs SHOULD be submitted to the new log and the SCTs from that log used
instead.</t>

</section>
<section anchor="iana-considerations" title="IANA Considerations">

<section anchor="tls-extension-type" title="TLS Extension Type">

<t>IANA is asked to allocate an RFC 5246 ExtensionType value for the
<spanx style="verb">transparency_info</spanx> TLS extension. IANA should update this extension type to
point at this document.</t>

</section>
<section anchor="new-entry-to-the-tls-cachedinformationtype-registry" title="New Entry to the TLS CachedInformationType registry">

<t>IANA is asked to add an entry for <spanx style="verb">ct_compliant(TBD)</spanx> to the "TLS
CachedInformationType Values" registry that was defined in <xref target="RFC7924"></xref>.</t>

</section>
<section anchor="hash_algorithms" title="Hash Algorithms">

<t>IANA is asked to establish a registry of hash algorithm values, initially
consisting of:</t>

<texttable>
      <ttcol align='left'>Index</ttcol>
      <ttcol align='left'>Hash</ttcol>
      <c>0</c>
      <c>SHA-256 <xref target="FIPS180-4"></xref></c>
      <c>255</c>
      <c>reserved</c>
</texttable>

</section>
<section anchor="signature_algorithms" title="Signature Algorithms">

<t>IANA is asked to establish a registry of signature algorithm values, initially
consisting of:</t>

<texttable>
      <ttcol align='left'>Index</ttcol>
      <ttcol align='left'>Signature Algorithm</ttcol>
      <c>0</c>
      <c>deterministic ECDSA <xref target="RFC6979"></xref> using the NIST P-256 curve (Section D.1.2.3 of the Digital Signature Standard <xref target="DSS"></xref>) and HMAC-SHA256.</c>
      <c>1</c>
      <c>RSA signatures (RSASSA-PKCS1-v1_5 with SHA-256, Section 8.2 of <xref target="RFC3447"></xref>) using a key of at least 2048 bits.</c>
</texttable>

</section>
<section anchor="sct_extension_types" title="SCT Extensions">

<t>IANA is asked to establish a registry of SCT extensions, initially consisting
of:</t>

<texttable>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Extension</ttcol>
      <c>65535</c>
      <c>reserved</c>
</texttable>

<t>TBD: policy for adding to the registry</t>

</section>
<section anchor="sth_extension_types" title="STH Extensions">

<t>IANA is asked to establish a registry of STH extensions, initially consisting
of:</t>

<texttable>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Extension</ttcol>
      <c>65535</c>
      <c>reserved</c>
</texttable>

<t>TBD: policy for adding to the registry</t>

</section>
<section anchor="object-identifiers" title="Object Identifiers">

<t>This document uses object identifiers (OIDs) to identify Log IDs (see
<xref target="log_id"/>), the precertificate CMS <spanx style="verb">eContentType</spanx> (see <xref target="precertificates"/>),
and X.509v3 extensions in certificates (see <xref target="name_constrained"/> and
<xref target="cert_transinfo_extension"/>) and OCSP responses (see
<xref target="ocsp_transinfo_extension"/>). The OIDs are defined in an arc that was selected
due to its short encoding.</t>

<section anchor="log_id_registry1" title="Log ID Registry 1">

<t>All OIDs in the range from 1.3.101.8192 to 1.3.101.16383 have been reserved.
This is a limited resource of 8,192 OIDs, each of which has an encoded length of
4 octets.</t>

<t>IANA is requested to establish a registry that will allocate Log IDs from this
range.</t>

<t>TBD: policy for adding to the registry. Perhaps "Expert Review"?</t>

</section>
<section anchor="log_id_registry2" title="Log ID Registry 2">

<t>The 1.3.101.80 arc has been delegated. This is an unlimited resource, but only
the 128 OIDs from 1.3.101.80.0 to 1.3.101.80.127 have an encoded length of only
4 octets.</t>

<t>IANA is requested to establish a registry that will allocate Log IDs from this
arc.</t>

<t>TBD: policy for adding to the registry. Perhaps "Expert Review"?</t>

</section>
</section>
</section>
<section anchor="security-considerations" title="Security Considerations">

<t>With CAs, logs, and servers performing the actions described here, TLS clients
can use logs and signed timestamps to reduce the likelihood that they will
accept misissued certificates. If a server presents a valid signed timestamp for
a certificate, then the client knows that a log has committed to publishing the
certificate. From this, the client knows that monitors acting for the subject of
the certificate have had some time to notice the misissue and take some action,
such as asking a CA to revoke a misissued certificate, or that the log has
misbehaved, which will be discovered when the SCT is audited. A signed timestamp
is not a guarantee that the certificate is not misissued, since appropriate
monitors might not have checked the logs or the CA might have refused to revoke
the certificate.</t>

<t>In addition, if TLS clients will not accept unlogged certificates, then site
owners will have a greater incentive to submit certificates to logs, possibly
with the assistance of their CA, increasing the overall transparency of the
system.</t>

<t><xref target="I-D.ietf-trans-threat-analysis"></xref> provides a more detailed threat analysis of the
Certificate Transparency architecture.</t>

<section anchor="misissued-certificates" title="Misissued Certificates">

<t>Misissued certificates that have not been publicly logged, and thus do not have
a valid SCT, are not considered compliant. Misissued certificates that do have
an SCT from a log will appear in that public log within the Maximum Merge Delay,
assuming the log is operating correctly. Thus, the maximum period of time during
which a misissued certificate can be used without being available for audit is
the MMD.</t>

</section>
<section anchor="detection-of-misissue" title="Detection of Misissue">

<t>The logs do not themselves detect misissued certificates; they rely instead on
interested parties, such as domain owners, to monitor them and take corrective
action when a misissue is detected.</t>

</section>
<section anchor="misbehaving_logs" title="Misbehaving Logs">

<t>A log can misbehave in several ways. Examples include failing to incorporate a
certificate with an SCT in the Merkle Tree within the MMD, presenting different,
conflicting views of the Merkle Tree at different times and/or to different
parties and issuing STHs too frequently. Such misbehavior is detectable and the
<xref target="I-D.ietf-trans-threat-analysis"></xref> provides more details on how this can be done.</t>

<t>Violation of the MMD contract is detected by log clients requesting a Merkle
inclusion proof (<xref target="get-proof-by-hash"/>) for each observed SCT. These checks can
be asynchronous and need only be done once per each certificate. In order to
protect the clients' privacy, these checks need not reveal the exact certificate
to the log. Instead, clients can request the proof from a trusted auditor (since
anyone can compute the proofs from the log) or communicate with the log via
proxies.</t>

<t>Violation of the append-only property or the STH issuance rate limit can be
detected by clients comparing their instances of the Signed Tree Heads. There
are various ways this could be done, for example via gossip (see
<xref target="I-D.ietf-trans-gossip"></xref>) or peer-to-peer communications or by sending STHs to
monitors (who could then directly check against their own copy of the relevant
log). A proof of misbehavior in such cases would be a series of STHs that were
issued too closely together, proving violation of the STH issuance rate limit,
or an STH with a root hash that does not match the one calculated from a copy of
the log, proving violation of the append-only property.</t>

</section>
<section anchor="deterministic_signatures" title="Deterministic Signatures">

<t>Logs are required to use deterministic signatures for the following reasons:</t>

<t><list style="symbols">
  <t>Using non-deterministic ECDSA with a predictable source of randomness means
that each signature can potentially expose the secret material of the signing
key.</t>
  <t>Clients that gossip STHs or report back SCTs can be tracked or traced if a log
was to produce multiple STHs or SCTs with the same timestamp and data but
different signatures.</t>
</list></t>

</section>
<section anchor="offering_multiple_scts" title="Multiple SCTs">

<t>By offering multiple SCTs, each from a different log, TLS servers reduce the
effectiveness of an attack where a CA and a log collude (see <xref target="multiple-scts"/>).</t>

</section>
</section>
<section anchor="acknowledgements" title="Acknowledgements">

<t>The authors would like to thank Erwann Abelea, Robin Alden, Andrew Ayer, Al
Cutter, David Drysdale, Francis Dupont, Adam Eijdenberg, Stephen Farrell, Daniel
Kahn Gillmor, Paul Hadfield, Brad Hill, Jeff Hodges, Paul Hoffman, Jeffrey
Hutzelman, Kat Joyce, Stephen Kent, SM, Alexey Melnikov, Linus Nordberg, Chris
Palmer, Trevor Perrin, Pierre Phaneuf, Melinda Shore, Ryan Sleevi, Martin Smith,
Carl Wallace and Paul Wouters for their valuable contributions.</t>

<t>A big thank you to Symantec for kindly donating the OIDs from the 1.3.101 arc
that are used in this document.</t>

</section>


  </middle>

  <back>

    <references title='Normative References'>





<reference  anchor='RFC2119' target='http://www.rfc-editor.org/info/rfc2119'>
<front>
<title>Key words for use in RFCs to Indicate Requirement Levels</title>
<author initials='S.' surname='Bradner' fullname='S. Bradner'><organization /></author>
<date year='1997' month='March' />
<abstract><t>In many standards track documents several words are used to signify the requirements in the specification.  These words are often capitalized. This document defines these words as they should be interpreted in IETF documents.  This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t></abstract>
</front>
<seriesInfo name='BCP' value='14'/>
<seriesInfo name='RFC' value='2119'/>
<seriesInfo name='DOI' value='10.17487/RFC2119'/>
</reference>



<reference  anchor='RFC2616' target='http://www.rfc-editor.org/info/rfc2616'>
<front>
<title>Hypertext Transfer Protocol -- HTTP/1.1</title>
<author initials='R.' surname='Fielding' fullname='R. Fielding'><organization /></author>
<author initials='J.' surname='Gettys' fullname='J. Gettys'><organization /></author>
<author initials='J.' surname='Mogul' fullname='J. Mogul'><organization /></author>
<author initials='H.' surname='Frystyk' fullname='H. Frystyk'><organization /></author>
<author initials='L.' surname='Masinter' fullname='L. Masinter'><organization /></author>
<author initials='P.' surname='Leach' fullname='P. Leach'><organization /></author>
<author initials='T.' surname='Berners-Lee' fullname='T. Berners-Lee'><organization /></author>
<date year='1999' month='June' />
<abstract><t>HTTP has been in use by the World-Wide Web global information initiative since 1990. This specification defines the protocol referred to as &quot;HTTP/1.1&quot;, and is an update to RFC 2068.  [STANDARDS-TRACK]</t></abstract>
</front>
<seriesInfo name='RFC' value='2616'/>
<seriesInfo name='DOI' value='10.17487/RFC2616'/>
</reference>



<reference  anchor='RFC3447' target='http://www.rfc-editor.org/info/rfc3447'>
<front>
<title>Public-Key Cryptography Standards (PKCS) #1: RSA Cryptography Specifications Version 2.1</title>
<author initials='J.' surname='Jonsson' fullname='J. Jonsson'><organization /></author>
<author initials='B.' surname='Kaliski' fullname='B. Kaliski'><organization /></author>
<date year='2003' month='February' />
<abstract><t>This memo represents a republication of PKCS #1 v2.1 from RSA Laboratories' Public-Key Cryptography Standards (PKCS) series, and change control is retained within the PKCS process.  The body of this document is taken directly from the PKCS #1 v2.1 document, with certain corrections made during the publication process.  This memo provides information for the Internet community.</t></abstract>
</front>
<seriesInfo name='RFC' value='3447'/>
<seriesInfo name='DOI' value='10.17487/RFC3447'/>
</reference>



<reference  anchor='RFC4627' target='http://www.rfc-editor.org/info/rfc4627'>
<front>
<title>The application/json Media Type for JavaScript Object Notation (JSON)</title>
<author initials='D.' surname='Crockford' fullname='D. Crockford'><organization /></author>
<date year='2006' month='July' />
<abstract><t>JavaScript Object Notation (JSON) is a lightweight, text-based, language-independent data interchange format.  It was derived from the ECMAScript Programming Language Standard.  JSON defines a small set of formatting rules for the portable representation of structured data.  This memo provides information for the Internet community.</t></abstract>
</front>
<seriesInfo name='RFC' value='4627'/>
<seriesInfo name='DOI' value='10.17487/RFC4627'/>
</reference>



<reference  anchor='RFC4648' target='http://www.rfc-editor.org/info/rfc4648'>
<front>
<title>The Base16, Base32, and Base64 Data Encodings</title>
<author initials='S.' surname='Josefsson' fullname='S. Josefsson'><organization /></author>
<date year='2006' month='October' />
<abstract><t>This document describes the commonly used base 64, base 32, and base 16 encoding schemes.  It also discusses the use of line-feeds in encoded data, use of padding in encoded data, use of non-alphabet characters in encoded data, use of different encoding alphabets, and canonical encodings.  [STANDARDS-TRACK]</t></abstract>
</front>
<seriesInfo name='RFC' value='4648'/>
<seriesInfo name='DOI' value='10.17487/RFC4648'/>
</reference>



<reference  anchor='RFC5246' target='http://www.rfc-editor.org/info/rfc5246'>
<front>
<title>The Transport Layer Security (TLS) Protocol Version 1.2</title>
<author initials='T.' surname='Dierks' fullname='T. Dierks'><organization /></author>
<author initials='E.' surname='Rescorla' fullname='E. Rescorla'><organization /></author>
<date year='2008' month='August' />
<abstract><t>This document specifies Version 1.2 of the Transport Layer Security (TLS) protocol.  The TLS protocol provides communications security over the Internet.  The protocol allows client/server applications to communicate in a way that is designed to prevent eavesdropping, tampering, or message forgery.  [STANDARDS-TRACK]</t></abstract>
</front>
<seriesInfo name='RFC' value='5246'/>
<seriesInfo name='DOI' value='10.17487/RFC5246'/>
</reference>



<reference  anchor='RFC5280' target='http://www.rfc-editor.org/info/rfc5280'>
<front>
<title>Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile</title>
<author initials='D.' surname='Cooper' fullname='D. Cooper'><organization /></author>
<author initials='S.' surname='Santesson' fullname='S. Santesson'><organization /></author>
<author initials='S.' surname='Farrell' fullname='S. Farrell'><organization /></author>
<author initials='S.' surname='Boeyen' fullname='S. Boeyen'><organization /></author>
<author initials='R.' surname='Housley' fullname='R. Housley'><organization /></author>
<author initials='W.' surname='Polk' fullname='W. Polk'><organization /></author>
<date year='2008' month='May' />
<abstract><t>This memo profiles the X.509 v3 certificate and X.509 v2 certificate revocation list (CRL) for use in the Internet.  An overview of this approach and model is provided as an introduction.  The X.509 v3 certificate format is described in detail, with additional information regarding the format and semantics of Internet name forms.  Standard certificate extensions are described and two Internet-specific extensions are defined.  A set of required certificate extensions is specified.  The X.509 v2 CRL format is described in detail along with standard and Internet-specific extensions.  An algorithm for X.509 certification path validation is described.  An ASN.1 module and examples are provided in the appendices.  [STANDARDS-TRACK]</t></abstract>
</front>
<seriesInfo name='RFC' value='5280'/>
<seriesInfo name='DOI' value='10.17487/RFC5280'/>
</reference>



<reference  anchor='RFC5652' target='http://www.rfc-editor.org/info/rfc5652'>
<front>
<title>Cryptographic Message Syntax (CMS)</title>
<author initials='R.' surname='Housley' fullname='R. Housley'><organization /></author>
<date year='2009' month='September' />
<abstract><t>This document describes the Cryptographic Message Syntax (CMS).  This syntax is used to digitally sign, digest, authenticate, or encrypt arbitrary message content.  [STANDARDS-TRACK]</t></abstract>
</front>
<seriesInfo name='STD' value='70'/>
<seriesInfo name='RFC' value='5652'/>
<seriesInfo name='DOI' value='10.17487/RFC5652'/>
</reference>



<reference  anchor='RFC5905' target='http://www.rfc-editor.org/info/rfc5905'>
<front>
<title>Network Time Protocol Version 4: Protocol and Algorithms Specification</title>
<author initials='D.' surname='Mills' fullname='D. Mills'><organization /></author>
<author initials='J.' surname='Martin' fullname='J. Martin' role='editor'><organization /></author>
<author initials='J.' surname='Burbank' fullname='J. Burbank'><organization /></author>
<author initials='W.' surname='Kasch' fullname='W. Kasch'><organization /></author>
<date year='2010' month='June' />
<abstract><t>The Network Time Protocol (NTP) is widely used to synchronize computer clocks in the Internet.  This document describes NTP version 4 (NTPv4), which is backwards compatible with NTP version 3 (NTPv3), described in RFC 1305, as well as previous versions of the protocol. NTPv4 includes a modified protocol header to accommodate the Internet Protocol version 6 address family.  NTPv4 includes fundamental improvements in the mitigation and discipline algorithms that extend the potential accuracy to the tens of microseconds with modern workstations and fast LANs.  It includes a dynamic server discovery scheme, so that in many cases, specific server configuration is not required.  It corrects certain errors in the NTPv3 design and implementation and includes an optional extension mechanism.   [STANDARDS-TRACK]</t></abstract>
</front>
<seriesInfo name='RFC' value='5905'/>
<seriesInfo name='DOI' value='10.17487/RFC5905'/>
</reference>



<reference  anchor='RFC6066' target='http://www.rfc-editor.org/info/rfc6066'>
<front>
<title>Transport Layer Security (TLS) Extensions: Extension Definitions</title>
<author initials='D.' surname='Eastlake 3rd' fullname='D. Eastlake 3rd'><organization /></author>
<date year='2011' month='January' />
<abstract><t>This document provides specifications for existing TLS extensions.  It is a companion document for RFC 5246, &quot;The Transport Layer Security (TLS) Protocol Version 1.2&quot;.  The extensions specified are server_name, max_fragment_length, client_certificate_url, trusted_ca_keys, truncated_hmac, and status_request.  [STANDARDS-TRACK]</t></abstract>
</front>
<seriesInfo name='RFC' value='6066'/>
<seriesInfo name='DOI' value='10.17487/RFC6066'/>
</reference>



<reference  anchor='RFC6125' target='http://www.rfc-editor.org/info/rfc6125'>
<front>
<title>Representation and Verification of Domain-Based Application Service Identity within Internet Public Key Infrastructure Using X.509 (PKIX) Certificates in the Context of Transport Layer Security (TLS)</title>
<author initials='P.' surname='Saint-Andre' fullname='P. Saint-Andre'><organization /></author>
<author initials='J.' surname='Hodges' fullname='J. Hodges'><organization /></author>
<date year='2011' month='March' />
<abstract><t>Many application technologies enable secure communication between two entities by means of Internet Public Key Infrastructure Using X.509 (PKIX) certificates in the context of Transport Layer Security (TLS). This document specifies procedures for representing and verifying the identity of application services in such interactions.   [STANDARDS-TRACK]</t></abstract>
</front>
<seriesInfo name='RFC' value='6125'/>
<seriesInfo name='DOI' value='10.17487/RFC6125'/>
</reference>



<reference  anchor='RFC6960' target='http://www.rfc-editor.org/info/rfc6960'>
<front>
<title>X.509 Internet Public Key Infrastructure Online Certificate Status Protocol - OCSP</title>
<author initials='S.' surname='Santesson' fullname='S. Santesson'><organization /></author>
<author initials='M.' surname='Myers' fullname='M. Myers'><organization /></author>
<author initials='R.' surname='Ankney' fullname='R. Ankney'><organization /></author>
<author initials='A.' surname='Malpani' fullname='A. Malpani'><organization /></author>
<author initials='S.' surname='Galperin' fullname='S. Galperin'><organization /></author>
<author initials='C.' surname='Adams' fullname='C. Adams'><organization /></author>
<date year='2013' month='June' />
<abstract><t>This document specifies a protocol useful in determining the current status of a digital certificate without requiring Certificate Revocation Lists (CRLs). Additional mechanisms addressing PKIX operational requirements are specified in separate documents.  This document obsoletes RFCs 2560 and 6277.  It also updates RFC 5912.</t></abstract>
</front>
<seriesInfo name='RFC' value='6960'/>
<seriesInfo name='DOI' value='10.17487/RFC6960'/>
</reference>



<reference  anchor='RFC6961' target='http://www.rfc-editor.org/info/rfc6961'>
<front>
<title>The Transport Layer Security (TLS) Multiple Certificate Status Request Extension</title>
<author initials='Y.' surname='Pettersen' fullname='Y. Pettersen'><organization /></author>
<date year='2013' month='June' />
<abstract><t>This document defines the Transport Layer Security (TLS) Certificate Status Version 2 Extension to allow clients to specify and support several certificate status methods.  (The use of the Certificate Status extension is commonly referred to as &quot;OCSP stapling&quot;.)  Also defined is a new method based on the Online Certificate Status Protocol (OCSP) that servers can use to provide status information about not only the server's own certificate but also the status of intermediate certificates in the chain.</t></abstract>
</front>
<seriesInfo name='RFC' value='6961'/>
<seriesInfo name='DOI' value='10.17487/RFC6961'/>
</reference>



<reference  anchor='RFC6979' target='http://www.rfc-editor.org/info/rfc6979'>
<front>
<title>Deterministic Usage of the Digital Signature Algorithm (DSA) and Elliptic Curve Digital Signature Algorithm (ECDSA)</title>
<author initials='T.' surname='Pornin' fullname='T. Pornin'><organization /></author>
<date year='2013' month='August' />
<abstract><t>This document defines a deterministic digital signature generation procedure.  Such signatures are compatible with standard Digital Signature Algorithm (DSA) and Elliptic Curve Digital Signature Algorithm (ECDSA) digital signatures and can be processed with unmodified verifiers, which need not be aware of the procedure described therein.  Deterministic signatures retain the cryptographic security features associated with digital signatures but can be more easily implemented in various environments, since they do not need access to a source of high-quality randomness.</t></abstract>
</front>
<seriesInfo name='RFC' value='6979'/>
<seriesInfo name='DOI' value='10.17487/RFC6979'/>
</reference>



<reference  anchor='RFC7633' target='http://www.rfc-editor.org/info/rfc7633'>
<front>
<title>X.509v3 Transport Layer Security (TLS) Feature Extension</title>
<author initials='P.' surname='Hallam-Baker' fullname='P. Hallam-Baker'><organization /></author>
<date year='2015' month='October' />
<abstract><t>The purpose of the TLS feature extension is to prevent downgrade attacks that are not otherwise prevented by the TLS protocol.  In particular, the TLS feature extension may be used to mandate support for revocation checking features in the TLS protocol such as Online Certificate Status Protocol (OCSP) stapling.  Informing clients that an OCSP status response will always be stapled permits an immediate failure in the case that the response is not stapled.  This in turn prevents a denial-of-service attack that might otherwise be possible.</t></abstract>
</front>
<seriesInfo name='RFC' value='7633'/>
<seriesInfo name='DOI' value='10.17487/RFC7633'/>
</reference>



<reference  anchor='RFC7924' target='http://www.rfc-editor.org/info/rfc7924'>
<front>
<title>Transport Layer Security (TLS) Cached Information Extension</title>
<author initials='S.' surname='Santesson' fullname='S. Santesson'><organization /></author>
<author initials='H.' surname='Tschofenig' fullname='H. Tschofenig'><organization /></author>
<date year='2016' month='July' />
<abstract><t>Transport Layer Security (TLS) handshakes often include fairly static information, such as the server certificate and a list of trusted certification authorities (CAs).  This information can be of considerable size, particularly if the server certificate is bundled with a complete certificate chain (i.e., the certificates of intermediate CAs up to the root CA).</t><t>This document defines an extension that allows a TLS client to inform a server of cached information, thereby enabling the server to omit already available information.</t></abstract>
</front>
<seriesInfo name='RFC' value='7924'/>
<seriesInfo name='DOI' value='10.17487/RFC7924'/>
</reference>


<reference anchor="DSS" target="http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf">
  <front>
    <title>Digital Signature Standard (DSS)</title>
    <author >
      <organization abbrev="NIST">National Institute of Standards and Technology</organization>
    </author>
    <date year="2009" month="June"/>
  </front>
  <seriesInfo name="FIPS" value="186-3"/>
</reference>
<reference anchor="FIPS180-4" target="http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf">
  <front>
    <title>Secure Hash Standard</title>
    <author >
      <organization abbrev="NIST">National Institute of Standards and Technology</organization>
    </author>
    <date year="2012" month="March"/>
  </front>
  <seriesInfo name="FIPS" value="180-4"/>
</reference>
<reference anchor="HTML401" target="http://www.w3.org/TR/1999/REC-html401-19991224">
  <front>
    <title>HTML 4.01 Specification</title>
    <author initials="D." surname="Raggett" fullname="David Raggett">
      <organization></organization>
    </author>
    <author initials="A." surname="Le Hors" fullname="Arnaud Le Hors">
      <organization></organization>
    </author>
    <author initials="I." surname="Jacobs" fullname="Ian Jacobs">
      <organization></organization>
    </author>
    <date year="1999" month="December" day="24"/>
  </front>
  <seriesInfo name="World Wide Web Consortium Recommendation" value="REC-html401-19991224"/>
</reference>


    </references>

    <references title='Informative References'>





<reference  anchor='RFC6962' target='http://www.rfc-editor.org/info/rfc6962'>
<front>
<title>Certificate Transparency</title>
<author initials='B.' surname='Laurie' fullname='B. Laurie'><organization /></author>
<author initials='A.' surname='Langley' fullname='A. Langley'><organization /></author>
<author initials='E.' surname='Kasper' fullname='E. Kasper'><organization /></author>
<date year='2013' month='June' />
<abstract><t>This document describes an experimental protocol for publicly logging the existence of Transport Layer Security (TLS) certificates as they are issued or observed, in a manner that allows anyone to audit certificate authority (CA) activity and notice the issuance of suspect certificates as well as to audit the certificate logs themselves.  The intent is that eventually clients would refuse to honor certificates that do not appear in a log, effectively forcing CAs to add all issued certificates to the logs.</t><t>Logs are network services that implement the protocol operations for submissions and queries that are defined in this document.</t></abstract>
</front>
<seriesInfo name='RFC' value='6962'/>
<seriesInfo name='DOI' value='10.17487/RFC6962'/>
</reference>



<reference anchor='I-D.ietf-trans-gossip'>
<front>
<title>Gossiping in CT</title>

<author initials='L' surname='Nordberg' fullname='Linus Nordberg'>
    <organization />
</author>

<author initials='D' surname='Gillmor' fullname='Daniel Gillmor'>
    <organization />
</author>

<author initials='T' surname='Ritter' fullname='Tom Ritter'>
    <organization />
</author>

<date month='July' day='8' year='2016' />

<abstract><t>The logs in Certificate Transparency are untrusted in the sense that the users of the system don't have to trust that they behave correctly since the behavior of a log can be verified to be correct.  This document tries to solve the problem with logs presenting a "split view" of their operations.  It describes three gossiping mechanisms for Certificate Transparency: SCT Feedback, STH Pollination and Trusted Auditor Relationship.</t></abstract>

</front>

<seriesInfo name='Internet-Draft' value='draft-ietf-trans-gossip-03' />
<format type='TXT'
        target='http://www.ietf.org/internet-drafts/draft-ietf-trans-gossip-03.txt' />
</reference>


<reference anchor="CrosbyWallach" target="http://static.usenix.org/event/sec09/tech/full_papers/crosby.pdf">
  <front>
    <title>Efficient Data Structures for Tamper-Evident Logging</title>
    <author initials="S." surname="Crosby" fullname="Scott A. Crosby">
      <organization></organization>
    </author>
    <author initials="D." surname="Wallach" fullname="Dan S. Wallach">
      <organization></organization>
    </author>
    <date year="2009" month="August"/>
  </front>
  <seriesInfo name="Proceedings of the 18th USENIX Security Symposium," value="Montreal"/>
</reference>
<reference anchor="EVSSLGuidelines" target="https://cabforum.org/wp-content/uploads/EV_Certificate_Guidelines.pdf">
  <front>
    <title>Guidelines For The Issuance And Management Of Extended Validation Certificates</title>
    <author >
      <organization>CA/Browser Forum</organization>
    </author>
    <date year="2007"/>
  </front>
</reference>
<reference anchor="Chromium.Policy" target="http://www.chromium.org/Home/chromium-security/certificate-transparency">
  <front>
    <title>Chromium Certificate Transparency</title>
    <author >
      <organization>The Chromium Projects</organization>
    </author>
    <date year="2014"/>
  </front>
</reference>
<reference anchor="JSON.Metadata" target="http://www.certificate-transparency.org/known-logs/log_list_schema.json">
  <front>
    <title>Chromium Log Metadata JSON Schema</title>
    <author >
      <organization>The Chromium Projects</organization>
    </author>
    <date year="2014"/>
  </front>
</reference>
<reference anchor="Chromium.Log.Policy" target="http://www.chromium.org/Home/chromium-security/certificate-transparency/log-policy">
  <front>
    <title>Chromium Certificate Transparency Log Policy</title>
    <author >
      <organization>The Chromium Projects</organization>
    </author>
    <date year="2014"/>
  </front>
</reference>




<reference anchor='I-D.ietf-trans-threat-analysis'>
<front>
<title>Attack and Threat Model for Certificate Transparency</title>

<author initials='S' surname='Kent' fullname='Stephen Kent'>
    <organization />
</author>

<date month='October' day='20' year='2016' />

<abstract><t>This document describes an attack model and discusses threats for the Web PKI context in which security mechanisms to detect mis-issuance of web site certificates are being developed.  The model provides an analysis of detection and remediation mechanisms for both syntactic and semantic mis-issuance.  The model introduces an outline of attacks to organize the discussion.  The model also describes the roles played by the elements of the Certificate Transparency (CT) system, to establish a context for the model.</t></abstract>

</front>

<seriesInfo name='Internet-Draft' value='draft-ietf-trans-threat-analysis-10' />
<format type='TXT'
        target='http://www.ietf.org/internet-drafts/draft-ietf-trans-threat-analysis-10.txt' />
</reference>




    </references>


<section anchor="v1_coexistence" title="Supporting v1 and v2 simultaneously">

<t>Certificate Transparency logs have to be either v1 (conforming to <xref target="RFC6962"></xref>) or
v2 (conforming to this document), as the data structures are incompatible and so
a v2 log could not issue a valid v1 SCT.</t>

<t>CT clients, however, can support v1 and v2 SCTs, for the same certificate,
simultaneously, as v1 SCTs are delivered in different TLS, X.509 and OCSP
extensions than v2 SCTs.</t>

<t>v1 and v2 SCTs for X.509 certificates can be validated independently. For
precertificates, v2 SCTs should be embedded in the TBSCertificate before
submission of the TBSCertificate (inside a v1 precertificate, as described in
Section 3.1. of <xref target="RFC6962"></xref>) to a v1 log so that TLS clients conforming to
<xref target="RFC6962"></xref> but not this document are oblivious to the embedded v2 SCTs. An issuer
can follow these steps to produce an X.509 certificate with embedded v1 and v2
SCTs:</t>

<t><list style="symbols">
  <t>Create a CMS precertificate as described in <xref target="precertificates"/> and submit it
to v2 logs.</t>
  <t>Embed the obtained v2 SCTs in the TBSCertificate, as described in
<xref target="cert_transinfo_extension"/>.</t>
  <t>Use that TBSCertificate to create a v1 precertificate, as described in
Section 3.1. of <xref target="RFC6962"></xref> and submit it to v1 logs.</t>
  <t>Embed the v1 SCTs in the TBSCertificate, as described in Section 3.3. of
<xref target="RFC6962"></xref>.</t>
  <t>Sign that TBSCertificate (which now contains v1 and v2 SCTs) to issue the
final X.509 certificate.</t>
</list></t>

</section>


  </back>
</rfc>

