Transport Layer Security (TLS) Authentication with Verifiable Credential (VC)
Internet-Draft draft-vesco-vcauthtls-02
Andrea Vesco
LINKS Foundation
andrea.vesco@linksfoundation.com
Leonardo Perugini
LINKS Foundation
leonardo.perugini@linksfoundation.com
25 July 2024
AREA
WG
TLS
VC
DID
DLT
This document defines a new certificate type and extension for the exchange of Verifiable Credentials in the handshake of the Transport Layer Security (TLS) protocol. The new certificate type is intended to add the Verifiable Credentials as a new means of authentication. The resulting authentication process leverages a distributed ledger as the root of trust of the TLS endpoints' public keys. The endpoints can use different distributed ledger technologies to store their public keys and to perform the TLS handshake.
About This Document
Status information for this document may be found at https://datatracker.ietf.org/doc/draft-vesco-vcauthtls/.
Source for this draft and an issue tracker can be found at https://github.com/Cybersecurity-LINKS/draft-vesco-vcauthtls.
Introduction
The Self-Sovereign Identity (SSI) is a decentralised identity model that gives an entity control over the data it uses to generate and prove its identity. SSI model relies on three fundamental elements: a distributed ledger as the Root of Trust (RoT) for public keys, Decentralized IDentifier [DID], and Verifiable Credential [VC]. An SSI aware entity builds his identity starting from generating its key pair (sk, pk). Then the entity stores pk in the distributed ledger of choice for other entities to authenticate it. An entity's DID is a pointer to the distributed ledger where other entities can retrieve its pk. A DID is a Uniform Resource Identifier (URI) in the form did:did-method-name:method-specific-id where method-name is the name of the [DID] Method used to interact with the distributed ledger and method-specific-id is the pointer to the [DID] Document that contains pk, stored in the distributed ledger. After that, the entity can request a VC from one of the Issuers available in the system. The VC contains the metadata to describe properties of the credential, the DID and the claims about the identity of the entity and the signature of the Issuer. The combination of the key pair (sk, pk), the DID and at least one VC forms the identity compliant with the SSI model. An entity requests access to services by presenting a Verifiable Presentation [VP]. The VP is an envelop of the VC signed by the entity holding the VC with its sk. The verifier authenticates the entity checking the validity and authenticity of the VP and the inner VC before granting or denying access to the requesting entity. Figure 1 shows step by step the generation of the identity and the authentication with VP.
Generation of the identity compliant with the SSI model and authentication with VP

                              --------
                             | Entity |
                             |        |
                              --------
                            identity = [{pk,sk}]

                              --------
                             | Entity |                        pk                         -----
                             |        | -----------------------------------------------> | DLT |
                              --------                                                   |     |
                            identity = [{pk,sk},DID]                                      -----

 --------    request VC       --------
| Issuer | <---------------- | Entity |
|        | ----------------> |        |
 --------        VC           --------
                            identity = [{pk,sk},DID,VC]

                              --------         VP(VC)      ----------     DID resolve     -----
                             | Entity | ----------------> | Verifier | ----------------> | DLT |
                             |        | <---------------- |          | <---------------- |     |
                              --------        ok/ko        ----------          pk         -----

The current implementations of the authentication process run at the application layer. A client estabhlishes a TLS channel authenticating the server with the server's X.509 certificate. Then the server authenticates the client that sends its VP at application layer (i.e. over the TLS channel already established). The mutual authentication with VPs occurs when also the server exchanges its VP with the client again at application layer.
SSI is emerging as an identity option for Internet of Thing and Edge devices in computing continuum environments. In these scenarios, (mutual) authentication with VP can take place directly at the TLS protocol layer, enabling the peer-to-peer interaction model envisaged by the SSI model. This document describes the extensions to TLS handshake protocol to support the use of VCs for authentication while preserving the interoperability with TLS endpoints that use X.509 certificates. The extensions enable server and mutual authentication using VC, X.509, Raw Public Key or a combination of two of them. The ability to perform hybrid authenticated handshakes supports the gradual deployment of SSI in existing systems. Moreover, the extension allows TLS endpoints to use different distributed ledger technologies to store their public keys and to authenticate the peers. The authentication process is successful if the TLS endpoints implement the DID Method to resolve the peer's DID.
This document uses italic formatting in the following sections to mark some paragraphs discussing items still under design: Section 5.2 and Section 5.4.
Conventions and Definitions
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.
Extensions
client_certificate_type and server_certificate_type extensions
The TLS extensions client_certificate_type and server_certificate_type defined in [RFC7250] are used to negotiate the type of Certificate messages used in TLS to authenticate the server and, optionally, the client. This section defines a new certificate type, called VC, for the TLS 1.3 handshake. The updated CertificateType enumeration, the corresponding addition to the CertificateEntry structure, and the Certificate message structure are shown below. CertificateType values are sent in the server_certificate_type and client_certificate_type extensions, and the CertificateEntry structures are included in the certificate chain sent in the Certificate message.

/* Managed by IANA */
enum {
   X509(0),
   RawPublicKey(2),
   VC(TBD),
   (255)
} CertificateType;

struct {
   select(certificate_type){
      // The new certificate type defined in this document
      case VC:
         opaque cert_data<1..2^24-1>;

      // RawPublicKey certificate type defined in RFC 7250
      case RawPublicKey:
         opaque ASN1_subjectPublicKeyInfo<1..2^24-1>;

      // X.509 certificate defined in RFC 5246
      case X509:
         opaque cert_data<1..2^24-1>;
   };
   Extension extensions<0..2^16-1>;
} CertificateEntry;

struct {
   opaque certificate_request_context<0..2^8-1>;
   CertificateEntry certificate_list<0..2^24-1>;
} Certificate;

As per [RFC7250], the client will send a list of certificate types in [endpoint]_certificate_type extension(s), the server processes the received extension(s) and selects one of the offered certificate types, returning the negotiated value in the EncryptedExtensions message. Note that there is no requirement for the negotiated value to be the same in client_certificate_type and server_certificate_type extensions sent in the same message. Client and server can use different certificate types as long as the peer is able to verify that specific type of certificate.
did_methods extension
This section defines the did_methods extension, used as part of an extended TLS 1.3 handshake when VC certificate type is used. ExtensionType now contains the did_methods entry.

enum {
   server_name(0),
   max_fragment_length(1),
   ..,
   did_methods(TBD),
   (65535)
} ExtensionType;

This extension contains a list of DID Methods an endpoint supports, i.e. a set of DLTs an endpoint can interact with to resolve the peer's DID. A client MUST send this extension in the extended ClientHello message only when it indicates Verifiable Credential support in the server_certificate_type extension. The server MUST send this extension in a CertificateRequest message only if it indicates Verifiable Credential in client_certificate_type extension. The extension format which uses the extension_data field, is used to carry the DIDMethodList structure. The structure of this new extension is shown below.

enum {
   name0(0),
   name1(1),
   name2(2),
   ..
   (65535)
} DIDMethod

struct {
   DIDMethod did_methods<2..2^16-2>
} DIDMethodList

The list of existing DID Methods is currently maintained by the W3C in [DID-Registries]. Each DID Method is expressed in the form of a string. This document proposes the DIDMethod enum to map these strings into integer values.
TLS Client and Server Handshake
Figure 2 shows the message flow for full TLS handshake.
Message Flow for full TLS Handshake

DLT          Client                               Server           DLT

      Key  ^ ClientHello
      Exch | + server_certificate_type*
           | + client_certificate_type*
           | + did_methods*
           | + signature_algorithms*
           v + key_share*  -------->
                                             ServerHello ^ Key
                                            + key_share* v Exch,
                                   {EncryptedExtensions} ^ Server
                            {+ server_certificate_type*} | Params
                            {+ client_certificate_type*} |
                                   {CertificateRequest*} |
                                        {+ did_methods*} v
                                          {Certificate*} ^
                                    {CertificateVerify*} | Auth
                                              {Finished} v
                           <-------- [Application Data*]
 DID Resolve
 <==========
           ^ {Certificate*}
      Auth | {CertificateVerify*}
           v {Finished}    -------->
                                                         DID Resolve
                                                         ==========>
             [Application Data] <---> [Application Data]

        +  Indicates noteworthy extensions sent in the
           previously noted message.
        *  Indicates optional or situation-dependent
           messages/extensions that are not always sent.
        {} Indicates messages protected using keys
           derived from a
           [sender]_handshake_traffic_secret.
        [] Indicates messages protected using keys
           derived from [sender]_application_traffic_secret_N.

ClientHello message
To express support for VC certificate type, a client MUST include the extension of type client_certificate_type or server_certificate_type in the extended ClientHello message as described in Section 4.1.2 of [RFC8446]. If the client sends the server_certificate_type extension indicating VC, it MUST also send the did_methods extension.
ServerHello message
When the server receives the ClientHello message containing the server_certificate_type extension and/or the client_certificate_type extension, the following scenarios are possible:
- The server does not support the extensions, omits them in EncryptedExtensions and the handshake proceeds with X.509 certificate(s).
- The server does not support any of the proposed certificate types and terminates the session with a fatal alert of type unsupported_certificate.
- Both client and server indicate support for the VC certificate type. The server selects VC certificate type, but the client did not send the did_methods extension in addition to the server_certificate_type extension. The server MUST terminate the session with a fatal alert of type missing_extension.
- Both client and server indicate support for the VC certificate type. The server selects VC certificate type, but the server's DID is not compatible with any of the DID Methods supported by the client and listed in the did_methods extension sent with the ClientHello message. This document defines two possible server behaviours (a) the server terminates the session with a fatal alert of type unsupported_did_methods, (b) the server sends a HelloRetryRequest (HRR) message with a new extension listing the DLTs in which it owns a DID. These design considerations apply: solution (a) requires defining a new fatal alert message type, and the client has no clues to perform a new successful TLS handshake; solution (b) requires defining a new HRR extension which could have privacy implications as it discloses the DLTs where the server owns its DIDs; on the other hand, this extension provides the client with clues to retry a successful new TLS handshake.
- Both client and server indicate support for the VC certificate type, the server MAY select the first (most preferred) certificate type from the client's list that is supported by both endpoints. It MAY include the client_certificate_type in the EncryptedExtensions message to request a certificate from the client. In case the server selects VC certificate type, it MUST also send the did_methods extension in the CertificateRequest message.
CertificateRequest message
The server sends the CertificateRequest message to request client authentication. It MUST include the did_methods extension if it indicates VC in the client_certificate_type extension. If the ClientHello contains the did_methods extension, the server MUST send a list of DID Methods client and server have in common. If the client does not send the did_methods extension the server MUST select a list of DID Methods it supports. A client that processes the CertificateRequest message that does not own a DID compatible with the DID Methods selected by the server MUST send a Certificate message containing no certificates, i.e. with the certificate_list field having length 0.
Certificate message
When the selected certificate type is VC, the certificate_list in the Certificate message MUST contain no more than one CertificateEntry with the content of the endpoint's Verifiable Credential. This document intends to mandate CBOR encoding for the Verifiable Credential. After decoding, the endpoint MUST follows the procedure in [VC] to verify the Verifiable Credential.
CertificateVerify message
As discussed in Section 1, an Holder wraps its own Verifiable Credential into a Verifiable Presentation and signs it before presenting it to a Verifier for authentication purposes. During the TLS handshake, when the selected certificate type is VC, the subsequent CertificateVerify message acts also as the Holder signature on the Verifiable Presentation. In fact, the signature is computed over the transcript hash that contains also the Verifiable Credential of the sender inside the Certificate message.
TLS handshake Examples
This section shows some examples of TLS handshakes using different combinations of certificate types.
Server authentication with Verifiable Credential
The example in Figure 3 shows a TLS 1.3 handshake with server authentication. The client sends the server_certificate_type extension indicating both VC and X.509 certificate types. In addition, the client sends the did_methods extension with the list of supported DID Methods. The client does not own an identity at the TLS level, therefore omits the client_certificate_type extension. The server selects VC certificate type, sends the EncryptedExtensions message with the server_certificate_type extension set to VC, and sends its Verifiable Credential into the Certificate message. After receiving the CertificateVerify and Finished messages, the client resolves the server's DID to retrieve the server pk and authenticate it.
TLS Server Uses Verifiable Credential

DLT         Client                                              Server

            ClientHello
            server_certificate_type=(VC,X.509)
            did_methods=(btcr,iota) -------->
                                                            ServerHello
                                                  {EncryptedExtensions}
                                           {server_certificate_type=VC}
                                                          {Certificate}
                                                    {CertificateVerify}
                                                             {Finished}
                                    <--------        [Application Data]
 DID Resolve
 <==========
            {Finished}              -------->
            [Application Data]      <------->        [Application Data]

Mutual authentication with Verifiable Credentials
The example in Figure 4 shows a TLS 1.3 handshake with mutual authentication where both client and server authenticate the peer using Verifiable Credentials. The client sends the server_certificate_type extension indicating both VC and X.509 certificate types along with the did_methods extension containing the list of supported DID Methods. The client also sends the client_certificate_type extension indicating its capability to provide both a Verifiable Credential and an X.509 certificate. The server sends the server_certificate_type set to VC, the client_certificate_type set to VC and the CertificateRequest message with the did_methods extension containig a set of DID Methods in common with the client. Client and server send their Verifiable Credential into their respective Certificate messages. After receiving the CertificateVerify and Finished messages, the client and then the server resolve the peer's DID to retrieve the associated pk and authenticate each other.
TLS Client and TLS Server Use Verifiable Credentials

DLT        Client                                    Server         DLT

           ClientHello
           server_certificate_type=(VC,X.509)
           client_certificate_type=(VC,X.509)
           did_methods=(btcr,ethr)
                              -------->
                                                ServerHello
                                      {EncryptedExtensions}
                               {server_certificate_type=VC}
                               {client_certificate_type=VC}
                                       {CertificateRequest}
                                  {did_methods=(btcr,ethr)}
                                              {Certificate}
                                        {CertificateVerify}
                                                 {Finished}
                              <--------  [Application Data]
 DID Resolve
 <==========
           {Certificate}
           {CertificateVerify}
           {Finished}         -------->
                                                           DID Resolve
                                                           ==========>
           [Application Data] <------->  [Application Data]

Mutual authentication with Client using Verifiable Credential and Server using X.509 Certificate
The example in Figure 5 shows a TLS 1.3 handshake with mutual authentication that combines the use of Verifiable Credential and X.509 certificate. The client uses a Verifiable Credential, and the server uses an X.509 certificate. The client sends the server_certificate_type extension indicating X.509 certificate types. The client also sends the client_certificate_type extension indicating its capability to provide both a Verifiable Credential and an X.509 certificate. The server sends the server_certificate_type set to X.509, the client_certificate_type set to VC and the CertificateRequest message with the did_methods extension containig the set of suported DID Methods. The server sends its X.509 certificate and the client its Verifiable Credential into their respective Certificate messages. After receiving the CertificateVerify and Finished messages, the server resolves the client DID to retrieve the client pk and authenticate it.
TLS Client Uses a Verifiable Credential and TLS Server Uses an X.509 Certificate

Client                                               Server         DLT

ClientHello
server_certificate_type=(X.509)
client_certificate_type=(VC,X.509)
                        -------->
                                                ServerHello
                                      {EncryptedExtensions}
                            {server_certificate_type=X.509}
                               {client_certificate_type=VC}
                                       {CertificateRequest}
                             {did_methods=(btcr,ethr,iota)}
                                              {Certificate}
                                        {CertificateVerify}
                                                 {Finished}
                        <--------        [Application Data]
{Certificate}
{CertificateVerify}
{Finished}              -------->
                                                           DID Resolve
                                                           ==========>
[Application Data]      <------->        [Application Data]

Mutual authentication with Client using X.509 Certificate and Server using Verifiable Credential
The example in Figure 6 complements the previous one showing a TLS 1.3 handshake with mutual authentication where the client uses X.509 certificate and the server a Verifiable Credential. The client sends the server_certificate_type extension indicating both VC and X.509 certificate types along with the did_methods extension containing the list of supported DID Methods. The client also sends the client_certificate_type extension indicating its capability to provide only an X.509 certificate. The server sends the server_certificate_type set to VC, the client_certificate_type set to X.509 and the CertificateRequest message. The server sends its Verifiable Credential, and the client its X.509 certificate into their respective Certificate messages. After receiving the CertificateVerify and Finished messages, the client resolves the server's DID to retrieve the server pk and authenticate the client.
TLS Client Uses an X.509 Certificate and TLS Server Uses a Verifiable Credential

DLT          Client                                              Server

             ClientHello
             server_certificate_type=(VC,X.509)
             client_certificate_type=(X.509)
             did_methods=(btcr,ethr,iota)
                                       -------->
                                                            ServerHello
                                                  {EncryptedExtensions}
                                           {server_certificate_type=VC}
                                        {client_certificate_type=X.509}
                                                   {CertificateRequest}
                                                          {Certificate}
                                                    {CertificateVerify}
                                                             {Finished}
                                       <--------     [Application Data]
 DID Resolve
 <==========
            {Certificate}
            {CertificateVerify}
            {Finished}                 -------->
            [Application Data]         <------->     [Application Data]

Security Considerations
All the security considerations presented in [RFC8446] applies to this document as well. Further considerations can be made on the DID resolution process. Assuming that a DID resolution is performed in clear, a man-in-the-middle could impersonate the DLT node, forge a DID Document containing the authenticating endpoint's DID, associate it with a key pair that he owns, and then return it to the DID resolver. Thus, the attacker is able to compute a valid CertificateVerify message by possessing the long term private key. In practice, the man-in-the-middle attacker breaks in transit the immutability feature provided by the DLT, i.e. the RoT for the public keys. A possible solution to this attack is to esthablish a TLS channel towards the DLT node and authenticate only the latter to rely on the received data. The DLT node MUST be authenticated through an X.509 certificate. The session resumption and 0 round-trip time (0-RTT) features of TLS 1.3 can be used to reduce the overhead of establishing this TLS channel. In addition, the communication with the DLT node can be protected with Internet Protocol Security (IPsec) [RFC4301] [RFC6071] in endpoint-to-endpoint transport mode for even better performance in term of latency of DID resolution. Mutual authentication in Internet Key Exchange Version 2 (IKEv2) [RFC7296] can be performed with raw public keys.
Privacy Considerations
Privacy issues can arise when the client resolves the server's DID on a public DLT node. The DLT node can monitor all the servers a client connects to. This problem disappears when DLT nodes are deployed as an integral part of the IoT system itself.
IANA Considerations
To be addressed
References
Normative References
[RFC7296]

Internet Key Exchange Protocol Version 2 (IKEv2)
C. Kaufman
P. Hoffman
Y. Nir
P. Eronen
T. Kivinen
October 2014
STD 79
RFC 7296
DOI 10.17487/RFC7296
[RFC4301]

Security Architecture for the Internet Protocol
S. Kent
K. Seo
December 2005
RFC 4301
DOI 10.17487/RFC4301
[RFC7250]

Using Raw Public Keys in Transport Layer Security (TLS) and Datagram Transport Layer Security (DTLS)
P. Wouters, Ed.
H. Tschofenig, Ed.
J. Gilmore
S. Weiler
T. Kivinen
June 2014
RFC 7250
DOI 10.17487/RFC7250
[RFC8446]

The Transport Layer Security (TLS) Protocol Version 1.3
E. Rescorla
August 2018
RFC 8446
DOI 10.17487/RFC8446
[RFC2119]

Key words for use in RFCs to Indicate Requirement Levels
S. Bradner
March 1997
BCP 14
RFC 2119
DOI 10.17487/RFC2119
[RFC8174]

Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words
B. Leiba
May 2017
BCP 14
RFC 8174
DOI 10.17487/RFC8174
Informative References
[RFC6071]

IP Security (IPsec) and Internet Key Exchange (IKE) Document Roadmap
S. Frankel
S. Krishnan
February 2011
RFC 6071
DOI 10.17487/RFC6071
[DID]

Decentralized Identifiers (DIDs) v1.0
W3C
July 2022
[DID-Registries]

DID Specification Registries
W3C
September 2023
[VC]

Verifiable Credentials Data Model v2.0
W3C
November 2023
[VP]

Verifiable Credentials Data Model v2.0
W3C
November 2023
Acknowledgments
We would like to thank Nicola Tuveri for his very helpful suggestions during the preparation of the first version of this technical specification.