Draft: draft-ietf-tls-ctls

Commentary: This is a radical change that attempts to implement the ( possible ) consensus to move from a " reconstruction - based " transcript to a " non - reconstruction " transcript . Verifying the transcript without reconstruction requires the transcript to include the template , which requires a byte - identical representation of the template . This change makes this possible by introducing a stable binary representation of the template , with  as a human - readable alternative . This change also attempts to : Formalize the notion of when vector lengths can be omitted Rearrange the extension templating in a more convenient fashion 
 Blocked by and 
 There was some discussion in the TLS session at IETF 113 about whether the Finished message should authenticate the reconstructed TLS transcript ( as currently ) or the cTLS transcript . We should try to reach a conclusion about this . Note that , if it is allowed to receive compression templates over an untrusted channel ( ) , authenticating the cTLS transcript would presumably require including the compression template in the transcript , to avoid cross - template attacks ( e.g. injecting the attacker 's without altering the transcript ) . To avoid hashing  ( which might be reformatted by intermediary systems ) , this would probably require defining a compact binary encoding of the  template ( which I would like to have ! ) . 
 " compact binary encoding " brings to mind CBOR . I think having a canonical / compat JSON format is beyond the scope of this doc . 
 CBOR is a possibility , but defining a compact , canonical CBOR representation might also be nontrivial . Personally , I would reuse the TLS extensions field format , with numeric key IDs and binary formats defined for each cTLS template element . 
 Perhaps reading RFC 8949 will change your mind . 
 My main concern about a generic JSON - CBOR conversion is that it is still an inefficient encoding , and I would like to be able to distribute cTLS profiles efficiently . A generic CBOR encoding would still have keys represented as strings , binary values represented in hexadecimal , etc . Even apart from efficiency , I still have concerns regarding canonicalization . For example , some JSON - handling intermediaries are likely to alter the order of keys in maps , convert integer - valued floats to integers , etc . 
 I was suggesting cbor as the inter - machine transport . As for keys - as - string , well , you are using json and therefore do n't have alternatives . Maybe use the TLS presentation language . It 's already part of TLS stacks , is pretty compact , and canonical . 
 I have the impression that the preference is to move to a non - reconstruction handshake . I 've written up a ( draft ) PR that implements that : . Unsurprisingly , this is a massive change to the document . includes the changes from the other two outstanding PRs , so they should be merged first . 
 I think this could use with some refinement , but it would be better in the draft than out .
This document specifies a "compact" version of TLS 1.3.  It is
isomorphic to TLS 1.3 but saves space by trimming obsolete material,
tighter encoding, a template-based specialization technique, and
alternative cryptographic techniques. cTLS is not directly
interoperable with TLS 1.3, but it should eventually be possible for
a cTLS/TLS 1.3 server to exist and successfully interoperate.
This document specifies a "compact" version of TLS and DTLS.  It is
logically isomorphic to ordinary TLS, but saves space by trimming
obsolete material, tighter encoding, a template-based specialization
technique, and alternative cryptographic techniques. cTLS is not
directly interoperable with TLS or DTLS, but it should eventually be
possible for a single server port to offer cTLS alongside TLS or
DTLS.
For the common (EC)DHE handshake with pre-established certificates,
cTLS achieves an overhead of 45 bytes over the minimum required by
the cryptovariables.  For a PSK handshake, the overhead is 21 bytes.
Annotated handshake transcripts for these cases can be found in
transcripts.
Because cTLS is semantically equivalent to TLS, it can be viewed
either as a related protocol or as a compression mechanism.
Specifically, it can be implemented by a layer between the TLS
handshake state machine and the record layer.
OPEN ISSUE: Semi-static and point compression are never mentioned
again.
For the common (EC)DHE handshake with pre-established certificates,
Stream cTLS achieves an overhead of 45 bytes over the minimum
required by the cryptovariables.  For a PSK handshake, the overhead
is 21 bytes.  Annotated handshake transcripts for these cases can be
found in transcripts.
TODO: Update these values.
cTLS supports the functionality of TLS and DTLS 1.3, and is forward-
compatible to future versions of TLS and DTLS.  cTLS itself is
versioned by "CTLSTemplate.version" (currently zero).
A significant transmission overhead in TLS 1.3 is contributed to by
two factors, : - the negotiation of algorithm parameters, and
extensions, as well as - the exchange of certificates.
the exchange of certificates.
The basic idea of template-based specialization is that we start with
the basic TLS 1.3 handshake, which is fully general and then remove
degrees of freedom, eliding parts of the handshake which are used to
express those degrees of freedom.  For example, if we only support
one version of TLS, then it is not necessary to have version
negotiation and the supported_versions extension can be omitted.
Importantly, this process is performed only for the wire encoding but
not for the handshake transcript.  The result is that the transcript
for a specialized cTLS handshake is the same as the transcript for a
TLS 1.3 handshake with the same features used.
The basic idea of template-based specialization is that we start with
the basic TLS 1.3 handshake, which is fully general and then remove
degrees of freedom, eliding parts of the handshake which are used to
express those degrees of freedom.  For example, if we only support
one version of TLS, then it is not necessary to have version
negotiation and the supported_versions extension can be omitted.
Thus, each specialization produces a new protocol that preserves the
security guarantees of TLS, but has its own unique handshake.
The compression profile defining the use of algorithms, algorithm
parameters, and extensions is specified via a JSON dictionary.
TODO: Reorder enum.
Elements in a "CTLSTemplate" MUST appear sorted by the type field in
strictly ascending order.  The initial elements are defined in the
subsections below.  Future elements can be added via an IANA registry
(template-keys).  When generating a template, all elements are
OPTIONAL to include.  When processing a template, all elements are
mandatory to understand (but see discussion of "optional" in
optional).
For ease of configuration, an equivalent JSON dictionary format is
also defined.  It consists of a dictionary whose keys are the name of
each element type (converted from snake_case to camelCase), and whose
values are a type-specific representation of the element intended to
maximize legibility.  The cTLS version is represented by the key
"ctlsVersion", whose value is an integer, defaulting to 0 if omitted.
OPEN ISSUE: Is it really worth converting snake_case to camelCase?
camelCase is slightly more traditional in JSON, and saves one
byte, but it seems annoying to implement.
indicates that both sides agree to the single TLS version
specified by the given integer value (772 == 0x0304 for TLS 1.3).
The supported_versions extension is omitted from
ClientHello.extensions and reconstructed in the transcript as a
single-valued list with the specified value.  The
supported_versions extension is omitted from
ClientHello.extensions and reconstructed in the transcript with
the specified value.
indicates that both sides agree to the single named cipher suite,
using the "TLS_AEAD_HASH" syntax defined in RFC8446, Section 8.4.
The ClientHello.cipher_suites field is omitted and reconstructed
in the transcript as a single-valued list with the specified
value.  The server_hello.cipher_suite field is omitted and
reconstructed in the transcript as the specified value.
specifies a single DH group to use for key establishment.  The
group is listed by the code point name in RFC8446, Section 4.2.7.
(e.g., x25519).  This implies a literal "supported_groups"
extension consisting solely of this group.
specifies a single signature scheme to use for authentication.
The signature algorithm is listed by the code point name in
RFC8446, Section 4.2.3. (e.g., ecdsa_secp256r1_sha256).  This
implies a literal "signature_algorithms" extension consisting
solely of this group.
indicates that the ClientHello.Random and ServerHello.Random
values are truncated to the given length.  When the transcript is
reconstructed, the Random is padded to the right with 0s and the
anti-downgrade mechanism in RFC8446, Section 4.1.3 is disabled.
IMPORTANT: Using short Random values can lead to potential
attacks.  The Random length MUST be less than or equal to 32
bytes.
if set to true, indicates that the client must authenticate with a
certificate by sending Certificate and a CertificateVerify
message.  The server MUST omit the CertificateRequest message, as
its contents are redundant.
indicates that the Finished value is to be truncated to the given
length.  When the transcript is reconstructed, the remainder of
the Finished value is filled in by the receiving side.
contains keys that are not required to be understood by the
client.  Server operators MUST NOT place a key in this section
unless the server is able to determine whether the key is in use
based on the client data it receives.  A key MUST NOT appear in
both the main template and the optional section.
If specialization of extensions is to be used, then the TLS stack
MUST order each vector of Extension values in ascending order
according to the ExtensionType.  This allows for a deterministic
reconstruction of the extension list.
If truncated Random values are to be used, then the TLS stack MUST
be configurable to set the remaining bytes of the random values to
zero.  This ensures that the reconstructed, padded random value
matches the original.
If truncated Finished values are to be used, then the TLS stack
MUST be configurable so that only the provided bytes of the
Finished are verified, or so that the expected remaining values
can be computed.
Extensions used in the ClientHello, ServerHello, EncryptedExtensions,
and CertificateRequest messages can be "predefined" in a compression
profile, so that they do not have to be sent on the wire.  A
predefined extensions object is a dictionary whose keys are extension
names specified in the TLS ExtensionTypeRegistry specified in
RFC8446.  The corresponding value is a hex-encoded value for the
ExtensionData field of the extension.
If the extensions list in the message is not sorted in ascending
order by extension type, it is an error, because the decompressed
message will not match.
If the ExtensionData of the extension does not match the value
in the dictionary, it is an error, because decompression will
not produce the correct result.
If the ExtensionData matches, then the extension is removed,
and not included in the compressed message.
If there is an extension in the compressed message with a type
that exists in the predefined extensions object, it is an error,
because such an extension would not have been sent by a sender
with a compatible compression profile.
For each entry in the predefined extensions dictionary, an
extension is added to the decompressed message with the specified
type and value.
The resulting vector of extensions MUST be sorted in ascending
order by extension type.
Note that the "version", "dhGroup", and "signatureAlgorithm" fields
in the compression profile are specific instances of this algorithm
for the corresponding extensions.
TODO: Reorder section.
This encodes the profile ID, if one is specified.  IDs whose decoded
length is 4 bytes or less are reserved (see reserved-profiles).  When
a reserved value is used (including the default value), other keys
MUST NOT appear in the template, and a client MUST NOT accept the
template unless it recognizes the ID.
In JSON, the profile ID is represented as a hexadecimal-encoded
string.
Value: a single "ProtocolVersion" (RFC8446, Section 4.1.2) that both
parties agree to use.  For TLS 1.3, the "ProtocolVersion" is 0x0304.
When this element is included, the "supported_versions" extension is
omitted from "ClientHello.extensions".
In JSON, the version is represented as an integer (772 = 0x0304 for
TLS 1.3).
Value: a single "CipherSuite" (RFC8446, Section 4.1.2) that both
parties agree to use.
When this element is included, the "ClientHello.cipher_suites" and
"ServerHello.cipher_suite" fields are omitted.
In JSON, the cipher suite is represented using the "TLS_AEAD_HASH"
syntax defined in RFC8446, Section 8.4.
Value: a single "NamedGroup" (RFC8446, Section 4.2.7) to use for key
establishment.
This is equivalent to a literal "supported_groups" extension
consisting solely of this group.
"KeyShareEntry.key_exchange", if the "NamedGroup" uses fixed-size
key shares.
In JSON, the group is listed by the code point name in RFC8446,
Section 4.2.7 (e.g., "x25519").
Value: a single "SignatureScheme" (RFC8446, Section 4.2.3) to use for
authentication.
This is equivalent to a literal "signature_algorithms" extension
consisting solely of this group.
In JSON, the signature algorithm is listed by the code point name in
RFC8446, Section 4.2.3. (e.g., ecdsa_secp256r1_sha256).
Value: a single "uint8".
The "ClientHello.Random" and "ServerHello.Random" values are
truncated to the given length.  Where a 32-byte "Random" is required,
the Random is padded to the right with 0s and the anti-downgrade
mechanism in RFC8446, Section 4.1.3 is disabled.  IMPORTANT: Using
short Random values can lead to potential attacks.  The Random length
MUST be less than or equal to 32 bytes.
In JSON, the length is represented as an integer.
Value: a single "uint8", with 1 representing "true" and 0
representing "false".  All other values are forbidden.
If set to true, this element indicates that the client must
authenticate with a certificate by sending Certificate and a
CertificateVerify message.  The server MUST omit the
CertificateRequest message, as its contents are redundant.
The "predefined_extensions" field indicates extensions that should be
treated as if they were included in the corresponding message.  This
allows these extensions to be omitted entirely.
The "expected_extensions" field indicates extensions that must be
included in the corresponding message, at the beginning of its
"extensions" field.  The types of these extensions are omitted when
serializing the "extensions" field of the corresponding message.
The "allow_additional" field MUST be 0 (false) or 1 (true),
indicating whether additional extensions are allowed here.
"predefined_extensions" and "expected_extensions" MUST be in strictly
ascending order by "ExtensionType", and a single "ExtensionType" MUST
NOT appear in both lists.  If the "version", "dh_group", or
"signature_algorithm" element appears in the template, the
corresponding "ExtensionType" MUST NOT appear here.
"Extension.extension_data" for any extension in
"expected_extensions" whose value has fixed length.  This applies
only to the corresponding message.
The "extensions" field of the corresponding message, if
"allow_additional" is false.
"predefinedExtensions": a dictionary mapping "ExtensionType" names
(RFC8446, Section 4.2) to values encoded as hexadecimal strings.
"expectedExtensions": an array of "ExtensionType" names.
"allowAdditional": "true" or "false".
If "predefinedExtensions" or "expectedExtensions" is empty, it MAY be
omitted.
OPEN ISSUE: Should we have a "certificate_entry_extensions"
element?
Value: "uint8", indicating that the Finished value is to be truncated
to the given length.
In JSON, this length is represented as an integer.
Value: "uint8", with 0 indicating "false" and 1 indicating "true".
If true, handshake messages MUST be conveyed inside a "Handshake"
(RFC8446, Section 4) struct on stream transports, or a
"DTLSHandshake" (RFC9147, Section 5.2) struct on datagram transports,
and MAY be broken into multiple records as in TLS and DTLS.
Otherwise, each handshake message is conveyed in a "CTLSHandshake" or
"CTLSDatagramHandshake" struct (ctlshandshake), which MUST be the
payload of a single record.
Value: a "CTLSTemplate" containing elements that are not required to
be understood by the client.  Server operators MUST NOT place an
element in this section unless the server is able to determine
whether the client is using it from the client data it receives.  A
key MUST NOT appear in both the main template and the optional
section.
In JSON, this value is represented in the same way as the
"CTLSTemplate" itself.
Entries in the certificate map must appear in strictly ascending
lexicographic order by ID.
The only cTLS records that are sent in plaintext are handshake
records (ClientHello and ServerHello/HRR) and alerts. cTLS alerts are
the same as TLS alerts and use the same content types.  For handshake
records, we set the "content_type" field to a fixed cTLS-specific
value to distinguish cTLS plaintext records from encrypted records,
TLS/DTLS records, and other protocols using the same 5-tuple.
OPEN ISSUE: The profile_id is needed in the ClientHello to inform
the server what compression profile to use.  For a ServerHello
this field is not required.  Should we make this field optional?
Some cTLS template elements imply that certain vectors (as defined in
RFC8446, Section 3.4) have a fixed number of elements during the
handshake.  These template elements note these "static vectors" in
their definition.  When encoding a "static vector", its length prefix
is omitted.
The length of "extensions" is omitted because "allowAdditional" is
false, so the number of items in "extensions" (i.e., 1) is known
in advance.
"extension_type" is omitted because it is specified by
"expected_extensions".
The length of "client_shares" is omitted because the use of
"dhGroup" implies that there can only be one "KeyShareEntry".
"KeyShareEntry.group" is omitted because it is specified by
"dhGroup".
The length of the "key_exchange" is omitted because the "x25519"
key share has a fixed size (32 bytes).
The only cTLS records that are sent in plaintext are handshake
records (ClientHello and ServerHello/HRR) and alerts. cTLS alerts are
the same as TLS/DTLS alerts and use the same content types.  For
handshake records, we set the "content_type" field to a fixed cTLS-
specific value to distinguish cTLS plaintext records from encrypted
records, TLS/DTLS records, and other protocols using the same
5-tuple.
The "profile_id" field MUST identify the profile that is in use.  A
zero-length ID corresponds to the cTLS default protocol.  The
server's reply does not include the "profile_id", because the server
must be using the same profile indicated by the client.
The HelloRetryRequest message is a true handshake message instead
of a specialization of ServerHello.
Version 772 corresponds to the hex representation 0x0304, named group
"29" (0x001D) represents X25519.
OPEN ISSUE: Should we have a registry of well-known profiles?
When "template.handshake_framing" is false, the cTLS transport layer
uses a custom handshake framing that saves space by relying on the
record layer for message lengths.  (This saves 3 bytes per message
compared to TLS, or 9 bytes compared to DTLS.)  This compact framing
is defined by the "CTLSHandshake" and "CTLSDatagramHandshake"
structs.
Any handshake type registered in the IANA TLS HandshakeType Registry
can be conveyed in a "CTLS[Datagram]Handshake", but not all messages
are actually allowed on a given connection.  This definition shows
the messages types supported in "CTLSHandshake" as of TLS 1.3 and
DTLS 1.3, but any future message types are also permitted.
Each "CTLSHandshake" or "CTLSDatagramHandshake" MUST be conveyed as a
single "CTLSClientPlaintext.fragment",
"CTLSServerPlaintext.fragment", or "CTLSCiphertext.encrypted_record",
and is therefore limited to a maximum length of "2^16-1" or less.
When operating over UDP, large "CTLSDatagramHandshake" messages will
also require the use of IP fragmentation, which is sometimes
undesirable.  Operators can avoid these concerns by setting
"template.handshakeFraming = true".
TLS and DTLS start the handshake with an empty transcript.  cTLS is
different: it starts the transcript with a "virtual message" whose
HandshakeType is "ctls_template" (template-handshaketype) containing
the "CTLSTemplate" used for this connection.  This message is
included in the transcript even though it is not exchanged during
connection setup, in order to ensure that both parties are using the
same template.  Subsequent messages are appended to the transcript as
usual.
When computing the handshake transcript, all handshake messages are
represented in TLS "Handshake" messages, as in DTLS 1.3 (RFC9147,
Section 5.2), regardless of "template.handshake_framing".
To ensure that all parties agree about what protocol is in use, the
Cryptographic Label Prefix used for the handshake SHALL be "Sctls "
for Stream cTLS and "Dctls " for Datagram cTLS.  (This is similar to
the prefix substitution in Section 5.9 of RFC9147).
The logical handshake layer consists of handshake messages that are
reconstructed following the instructions in the template.  At this
layer, predefined extensions are reintroduced, truncated Random
values are extended, and all information is prepared to enable the
cryptographic handshake and any import or export of key material and
configuration.
There is no obligation to reconstruct logical handshake messages in
any specific format, and client and server do not need to agree on
the precise representation of these messages, so long as they agree
on their logical contents.
In general, we retain the basic structure of each individual TLS or
DTLS handshake message.  However, the following handshake messages
have been modified for space reduction and cleaned up to remove pre-
TLS 1.3 baggage.
In cTLS, the HelloRetryRequest message is a true handshake message
instead of a specialization of ServerHello.  The HelloRetryRequest
has the following format.
OPEN ISSUE: Does "server_hello_extensions" apply to
"HelloRetryRequest"?
Version 772 corresponds to the hex representation 0x0304 (i.e. 1.3).
IANA is requested to add the following entry to the TLS HandshakeType
registry.
DTLS-OK: ??? Not clear what to put here.
Comment: Virtual message used in cTLS.
This document requests that IANA change the name of entry 6 in the
TLS HandshakeType Registry from "hello_retry_request_RESERVED" to
"hello_retry_request", and set its Reference field to this document.
ID value: A sequence of 1-4 octets.
Template: A JSON object.
Note: An explanation or reference.
The ID values of length 1 are subject to a "Standards Action"
registry policy.  Values of length 2 are subject to an "RFC Required"
policy.  Values of length 3 and 4 are subject to a "First Come First
Served" policy.  Values longer than 4 octets are not subject to
registration and MUST NOT appear in this registry.