<?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.2.7 -->

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

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

<rfc docName="draft-friel-tls-over-http-00" category="std">

  <front>
    <title abbrev="ATLS">Application-Layer TLS</title>

    <author initials="O." surname="Friel" fullname="Owen Friel">
      <organization>Cisco</organization>
      <address>
        <email>ofriel@cisco.com</email>
      </address>
    </author>
    <author initials="R." surname="Barnes" fullname="Richard Barnes">
      <organization>Cisco</organization>
      <address>
        <email>rlb@ipv.sx</email>
      </address>
    </author>
    <author initials="M." surname="Pritikin" fullname="Max Pritikin">
      <organization>Cisco</organization>
      <address>
        <email>pritikin@cisco.com</email>
      </address>
    </author>

    <date year="2017" month="October" day="30"/>

    
    
    

    <abstract>


<t>Many clients need to establish secure connections to application services but face challenges establishing these connections due to the presence of middleboxes that terminate TLS connections from the client and restablish new TLS connections to the service. This document defines a mechanism for transporting TLS records in HTTP message bodies between clients and services. This enables clients and services to establish secure connections using TLS at the application layer, and treat any middleboxes that are intercepting traffic at the network layer as untrusted transport. In short, this mechanism moves the TLS handshake up the OSI stack to the application layer.</t>



    </abstract>


  </front>

  <middle>


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

<t>There are far more classes of clients being deployed on today’s networks than at any time previously. This poses challenges for network administators who need to mange their network and the clients connecting to their network, and poses challenges for client vendors and client software developers who must ensure that their clients can connect to all required services.</t>

<t>One common example is where a client is deployed on a local domain network that protects its perimeter using a TLS terminating middlebox, and the client needs to establish a secure connection to a service in a different network via the middlebox. Traditionally, this has been enabled by the network administrator deploying the necessary certificate authority trusted roots on the client. This can be achieved at scale using standard tools that enable the administrator to automatically push trusted roots out to all client machines in the network from a centralised domain controller. This works for for personal computers, laptops and servers running standard Operating Systems that can be centrally managed. This client management process breaks for multilpe classes of clients that are being deployed today, there is no standard mechanism for configuring trusted roots on these clients, and there is no standard mechaism for these clients to securely traverse middleboxes.</t>

<t>The TLS over HTTP mechanism defined in this document enables clients to traverse middleboxes that restrict communications to HTTP traffic they have inserted themselves into, and establish secure connections to services across network domain boundaries.</t>

</section>
<section anchor="terminology" title="Terminology">

<t>TLS over HTTP is referred to as ATLS throughout this document i.e. “Application Layer TLS”.</t>

</section>
<section anchor="atls-transport-goals" title="ATLS Transport Goals">

<t>The high level goals driving the design of this mechanism are:</t>

<t><list style="symbols">
  <t>reuse existing TLS specifications <xref target="RFC5246"/> <xref target="I-D.ietf-tls-tls13"/> as is without requiring any protocol changes</t>
  <t>work with all versions of TLS</t>
  <t>do not require any changes to current TLS software stacks</t>
  <t>do not mandate constraints on how the TLS stack is configured or used</t>
  <t>be forward compatible with future TLS versions</t>
  <t>work with both HTTP and HTTPS transport</t>
  <t>avoid introducing TLS protocol handling logic or semantics into the HTTP application layer i.e. TLS protocol knowledge and logic is handled by the TLS stack, HTTP is just a dumb transport</t>
  <t>ensure the client and server software implementations are as simple as possible</t>
</list></t>

</section>
<section anchor="architecture-overview" title="Architecture Overview">

<section anchor="network-architecture" title="Network Architecture">

<t>A typical network deployment is illustrated in Figure 1. It shows a client connecting to a service via a middlebox. It also shows a TLS terminator deployed in front of the service. The client establishes a transport layer TLS connection with the middlebox (C-&gt;M TLS), the middlebox in turn opens a transport layer TLS connection with the TLS terminator deployed in front of the service (M-&gt;T TLS). The client can ignore any certificate validation errors when it connects to the middlebox. HTTP messages are transported over this layer between the client and the service. Finally, application layer TLS messages are exchanged inside the HTTP message bodies in order to establish an end-to-end TLS session between the client and the service (C-&gt;S TLS).</t>

<figure title="Network Architecture" anchor="net-arch"><artwork><![CDATA[
       +----------+        +----------+
       | App Data |        | App Data |
       +----------+        +----------+         +----------+
       | C->S TLS |        | C->S TLS |         | App Data |
       +----------+        +----------+         +----------+
       |   HTTP   |        |   HTTP   |         | C->S TLS |
       +----------+        +----------+         +----------+
       | C->M TLS |        | M->T TLS |         |   HTTP   |
       +----------+        +----------+         +----------+
       |   TCP    |        |   TCP    |         |   TCP    |
       +----------+        +----------+         +----------+

+--------+      +-----------+      +----------------+     +---------+
| Client |----->| Middlebox |----->| TLS Terminator |---->| Service |
+--------+      +-----------+      +----------------+     +---------+
   ^                                                           ^
   |                                                           |
   +--------------Client to Service TLS Connection-------------+
]]></artwork></figure>

</section>
<section anchor="application-architecture" title="Application Architecture">

<t>TLS software stacks allow application developers to ‘unplug’ the default network socket transport layer and read and write TLS records directly from byte buffers. This enables application developers to create application layer TLS sessions, extract the raw TLS record bytes from the bottom of the TLS stack, and transport these bytes over any suitable transport. The TLS software stacks can generate byte streams of full TLS flights which may include multiple TLS records. This is illustrated in Figure 2 below.</t>

<figure title="TLS Stack Interfaces" anchor="tls-interface"><artwork><![CDATA[
                    +------------+                    +---------+
 Handshake Records  |            | Handshake Records  |         |
------------------->|    TLS     |------------------->|         |
                    |            |                    |  Byte   |
 Unencrypted Data   |  Software  | Encrypted Data     |         |
------------------->|            |------------------->| Buffers |
                    |   Stack    |                    |         |
 Encrypted Data     |            | Unencrypted Data   |         |
------------------->|            |------------------->|         |
                    + -----------+                    +---------+
]]></artwork></figure>

<t>These TLS software stack APIs enable application developers to build the software architecture illustrated in Figure 3. The application creates and interacts with an application layer TLS session in order to generate and consume raw TLS records. The application transports these raw TLS records inside HTTP message bodies using a standard HTTP stack. The HTTP stack may in turn use either TLS or TCP transport to comunicate with the peer. The application layer TLS session and network layer TLS session can both leverage a shared, common TLS software stack. This high level architecture is applicable to both clients and services.</t>

<figure title="Application Architecture" anchor="app-architecture"><artwork><![CDATA[
+-------------+ 
|             |  App
|             |  Data   +---------+
| Application |<------->|   App   |    +---------+
|             |  TLS    |   TLS   |--->|   TLS   |
|             | Records | Session |    |  Stack  |
|        +--->|<------->|         |    +---------+
|        |    |         +---------+         ^
|        |    |                             |
|        |    |  JSON   +-------+    +-------------+    +-----------+
|        |    | Payload | HTTP  |    |  Transport  |    |  TCP/IP   |
|        +--->|<------->| Stack |--->| TLS Session |--->| Transport |
+-------------+         +-------+    +-------------+    +-----------+
]]></artwork></figure>

</section>
<section anchor="application-arthiecture-benefits" title="Application Arthiecture Benefits">

<t>There are several benefits to using a standard TLS software stack to establish an application layer secure communications channel between a client and a service. These include:</t>

<t><list style="symbols">
  <t>no need to define a new cryptographic negotiation and exchange protocol beween client and service</t>
  <t>automatically benefit from new cipher suites by simply upgrading the TLS software stack</t>
  <t>automaticaly benefit from new features, bugfixes, etc. in TLS software stack upgrades</t>
</list></t>

</section>
<section anchor="implementation" title="Implementation">

<t>Pseudo code illustrating how to read and write TLS records directly from byte buffers using both OpenSSL and Java JSSE is given in the appendices.</t>

</section>
</section>
<section anchor="atls-overview" title="ATLS Overview">

<t>The assumption is that the client will establish a transport layer connection to the server for exchange of HTTP messages. The underlying transport layer connection could be over TCP or TLS. The client will then establish an application layer TLS connection with the server by exchanging TLS records with the server inside HTTP message requests and responses.</t>

<section anchor="tls-connections" title="TLS Connections">

<t>If the underlying transport layer connection is TLS, this means that the client will establish two independent TLS connections:</t>

<t><list style="symbols">
  <t>one at the transport layer which could be directly with the service or could be with a middlebox</t>
  <t>one at the application layer which will be with the service</t>
</list></t>

<t>As an optimisation, clients may choose to only use ATLS as a fallback mechanism if certificate validation fails on the transport layer TLS connection to the service. For the purposes of establishing a secure connection with the service, the client does not need to perform any certificate checks or validation on the transport layer TLS connection.</t>

<t>Similarly, the service may also establish two independent TLS connections:</t>

<t><list style="symbols">
  <t>one at the transport layer which could be directly with the client or could be with a middlebox</t>
  <t>one at the application layer which will be with the client</t>
</list></t>

<t>Once the application layer TLS connection is estabilshed, the client may report to the service the TLS certificates that where presented by the network layer TLS connection but this is application specific behaviour and outside the scope of this specification.</t>

</section>
<section anchor="protocol-introduction" title="Protocol Introduction">

<t>All application TLS records are transported as base64 encoded payloads inside JSON message bodies over HTTP transport. Each payload contains a full TLS flight made up of one or more TLS records.</t>

<t>The client sends all application TLS records to the server in JSON message bodies in POST requests.</t>

<t>The server sends all TLS records to the client in JSON message bodies in 200 OK responses to the POST requests.</t>

<t>No constraints are placed on the ContentType contained within the transported TLS records. The TLS records may contain handshake, application_data, alert or change_cipher_spec messages. If new ContentType messages are defined in future TLS versions, these may also be transported using this protocol.</t>

<t>If the server is able to handle the application layer TLS records included in the request, the server always responds with a 200 OK and includes any application TLS records in the message body. The server does not, for example, parse the TLS records generated by its TLS software stack for an AlertDescription and attempt to map this to a suitable HTTP error response code.</t>

<t>The server only responds with a non-200 OK message if a server error occurrs and it is not capable of handling the application layer TLS message received from the client.</t>

</section>
<section anchor="tls-session-tracking" title="TLS Session Tracking">

<t>The service needs to track multiple client application layer TLS sessions so that it can collerate TLS records received in HTTP message bodies with the appropriate TLS session. It does this by inclusion of an explicit session identifier in the JSON message body.</t>

</section>
<section anchor="upgrade-to-websocket" title="Upgrade to Websocket">

<t>The HTTP connection between the client and the service may be upgraded to a websocket if required. This would allow a server to send a TLS close request, or any application data, asynchronously to the client. Note that for the majority of use cases, there will be no need to open a websocket between the client and service.</t>

</section>
<section anchor="service-container-affinity" title="Service Container Affinity">

<t>Application services are typically distributed across multiple containers and virtual machines. As TLS is stateful, it must be ensured that sequences of TLS messages are handled appropriately by the service deployment and the service execution engine has access to all necessary state information. This is explicilty outside the scope of this specification as there are multiple well defined mechanisms for enabling this.</t>

</section>
<section anchor="keying-material-exporting" title="Keying Material Exporting">

<t>This specification does not require, or preclude, the use of <xref target="RFC5705"/>. When the client and service applications detect that the ATLS session is established, the application may use the key exporter functions of the TLS stack to derive shared keys between client and service. The client and service may then use these shared keys to establish an independent cryptographic context and exchange data using any suitable mechanism such as JSON Web Encryption <xref target="RFC7516"/> or Encrypted Content-Encoding for HTTP <xref target="RFC8188"/>.</t>

</section>
</section>
<section anchor="protocol-details" title="Protocol Details">

<section anchor="message-body" title="Message Body">

<t>All message bodies are JSON bodies containing one or two parameters:</t>

<figure><artwork><![CDATA[
{
  "session": "<session-string>", 
  "records": "<base64 encoded TLS records>"
}
]]></artwork></figure>

<t>The following two parameters are defined:</t>

<t>session:
  This is set by the service and is used to correlate requests across multiple client sessions. This parameter is included in all messages apart from the first first message sent from the client to the service.  When a client sends the first request to establish an ATLS session with a service, it MUST omit this parameter. When a service handles the first request from a client (and that request will include the ClientHello), and the service creates an internal TLS session object, it MUST return a server-generated <spanx style="verb">&lt;session-string&gt;</spanx> to the client. The client MUST include that <spanx style="verb">&lt;session-string&gt;</spanx> in all subsequent messages to the server. If the service is unable to find a TLS session that correlates with the <spanx style="verb">&lt;session-string&gt;</spanx> that a client specifies, the server MUST return 422 Unprocessable Entity.</t>

<t>records:
  This parameter is used to transport the base64 encoded TLS records that the client and service applications retrieve from their TLS stack. This parameter is sent in all requests from the client to the service. This parameter may not necessarily be sent in all response messages from the service to the client if the service has no TLS records to send. This can happen with a TLS1.3 handshake.</t>

</section>
<section anchor="http-content-type" title="HTTP Content-Type">

<t>A new HTTP Content-Type is defined:</t>

<figure><artwork><![CDATA[
Content-Type: application/atls+json
]]></artwork></figure>

</section>
<section anchor="client-requests" title="Client Requests">

<t>When a client has base64 encoded TLS records to send to a service, it will include the previously received <spanx style="verb">&lt;session-string&gt;</spanx> in the request, or else omit this field for the very first handshake message, and send the following request to the service:</t>

<figure><artwork><![CDATA[
POST /atls
Content-Type: application/atls+json

{
  "session": "<session-string>", 
  "records": "<base64 encoded TLS records>"
}
]]></artwork></figure>

</section>
<section anchor="server-responses" title="Server Responses">

<t>When a service has processed the TLS records received from a client and has generated TLS records to reply with, it will send the following reply to the client:</t>

<figure><artwork><![CDATA[
200 OK
Content-Type: application/atls+json

{
  "session": "<session-string>", 
  "records": "<base64 encoded TLS records>"
}
]]></artwork></figure>

<t>The server MUST respond with one of the following status codes:</t>

<t><list style="hanging">
  <t hangText='200 OK:'>
  The server was able to successfully parse the request and process
the TLS records using its TLS software stack.</t>
  <t hangText='400 Bad Request:'>
  The client’s request did not contain a JSON object of the form
specified above.</t>
  <t hangText='422 Unprocessable Entity:'>
  The client presented a <spanx style="verb">&lt;session-string&gt;</spanx> that the service is
unable to correlate that to an existing TLS session.</t>
</list></t>

<t>Note that a status code of 200 OK does not indicate that the TLS
connection being negotiated is error-free.  Alerts produced by TLS
will be returned in the encoded TLS records.  A 200 OK response
simply indicates that the client should provide the records encoded
in the response to its TLS stack.</t>

</section>
</section>
<section anchor="atls-session-establishment" title="ATLS Session Establishment">

<t>This section describes a typical ATLS session establishment flow.</t>

<section anchor="atls-handshake-message-sequence-flow" title="ATLS Handshake Message Sequence Flow">

<t>The following flow chart shows an illustrative message sequence flow for the first TLS handshake flight between a client and a service.</t>

<figure><artwork><![CDATA[
+-------------------------------+  +-------------------------------+
|             Client            |  |           ATLS Server         |
+---------+---+-----+---+-------+  +-------+---+-----+---+---------+
|   TLS   |   | App |   | HTTP  |  | HTTP  |   | App |   |   TLS   |
| Session |   +-----+   | Stack |  | Stack |   +-----+   | Session |
+---------+       |     +-------+  +-------+       |     +---------+
     |            |         |           |          |          |
     |            |         |  HTTP(S)  |          |          |
     |            |         | Transport |          |          |
     |   Create   |         |<--------->|          |          |
     |   Session  |         |           |          |          |
     |<-----------|         |           |          |          |
     |    Start   |         |           |          |          |
     |  Handshake |         |           |          |          |
     |<-----------|         |           |          |          |
     |    TLS     |         |           |          |          |
     |  Records   | Package |           |          |          |
     |----------->|  JSON   |           |          |          |
     |            |-------->|   POST    | Unwrap   |          |
     |            |         |---------->|  JSON    | Create   |
     |            |         |           |--------->| Session  |
     |            |         |           |          |--------->|
     |            |         |           |          |   TLS    |
     |            |         |           |          | Records  |
     |            |         |           |          |--------->|
     |            |         |           |          |   TLS    |
     |            |         |           | Package  | Records  |
     |            |         |           |  JSON    |<---------|
     |            | Unwrap  |  200 OK   |<---------|          |
     |    TLS     |  JSON   |<----------|          |          |
     |  Records   |<--------|           |          |          |
     |<-----------|         |           |          |          |
     |    TLS     |         |           |          |          |
     |  Records   |         |           |          |          |
     |----------->|         |           |          |          |
]]></artwork></figure>

<t>This process repeats until the handshake completes.  Once the
application-layer TLS connection is ready to carry application data,
the ATLS server relays it to the application server that is
ultimately serving the rqeuest.  That is, a given ATLS server is
assumed to be connected to a single application endpoint.</t>

<figure><artwork><![CDATA[
                    +--------+           +--------+
+--------+          |  ATLS  |           |  App   |
| Client |          | Server |           | Server |
+--------+          +--------+           +--------+
    |                   |                    |
    |   TLS Handshake   |                    |
    |    (POST/200)     |                    |
    |<----------------->|                    |
    |                   |                    |
    | Application Data  |                    |
    |    (POST/200)     |  Application Data  |
    |<----------------->|<------------------>|
]]></artwork></figure>

</section>
<section anchor="detailed-atls-handshake" title="Detailed ATLS Handshake">

<t><list style="symbols">
  <t>Client establishes transport layer connection with service</t>
</list></t>

<t>This transport layer session can be established over TCP or TLS. If over TLS, the client does not need to perform certificate validation on the TLS connection, and may ignore any certificate validation errors if it does perform certificate validation.</t>

<t><list style="symbols">
  <t>Client creates an application TLS session object</t>
</list></t>

<t>The client application creates a TLS session object that is not bound to any network socket. The client initiates a TLS handshake on the session. This will result in the TLS session generating the TLS record bytes for a full TLS handshake first flight. This will be a ClientHello message. Note that the client application does not explicitly know what the contents of the TLS record bytes are.</t>

<t><list style="symbols">
  <t>The client base64 encodes the TLS flight 1 records and sends them in a HTTP POST to the service</t>
</list></t>

<figure><artwork><![CDATA[
POST /atls
Content-Type: application/atls

{
  "records": "<base64 encoded flight 1>" 
}
]]></artwork></figure>

<t><list style="symbols">
  <t>The service creates a TLS session for handling the request</t>
</list></t>

<t>The service notes that there is no <spanx style="verb">session</spanx> in the request and creates an application TLS session object and a suitable <spanx style="verb">&lt;session-string&gt;</spanx> for correlation. The service decodes the received base64 encoded <spanx style="verb">records</spanx> and passes them to the TLS session. The session handles the TLS handshake message and generates a full TLS handshake response flight. Typically, this will be a ServerHello and additional handshake messages that are TLS version dependent. For TLS1.3, this may include a Finished message. Note that the service application does not explicitly know what the contents of the TLS record bytes are.</t>

<t><list style="symbols">
  <t>The service base64 encodes the TLS flight 1 response records and sends them in the response to the client</t>
</list></t>

<t>The service MUST include its generated <spanx style="verb">session</spanx>.</t>

<figure><artwork><![CDATA[
200 OK
Content-Type: application/atls

{
  "session": "<session-string>",
  "records": "<base64 encoded flight 1 response>"
}
]]></artwork></figure>

<t><list style="symbols">
  <t>The client passes the service response to its TLS session</t>
</list></t>

<t>The client decodes the received base64 encoded <spanx style="verb">records</spanx> and passes them to the TLS session. The session handles the TLS handshake message and generates a full TLS handshake second flight.  This will be a Finished message, Certificate and CertificateVerify messages if required, and additional handshake messages that are TLS version dependent.</t>

<t><list style="symbols">
  <t>The client base64 encodes the TLS flight 2 records and sends them in a HTTP POST to the service</t>
</list></t>

<t>The client MUST include the <spanx style="verb">&lt;session-string&gt;</spanx> it received from the service.</t>

<figure><artwork><![CDATA[
POST /atls
Content-Type: application/atls

{
  "session": "<session-string>", 
  "records": "<base64 encoded flight 2>"
}
]]></artwork></figure>

<t><list style="symbols">
  <t>The service passes the client response to the respective TLS session</t>
</list></t>

<t>The service extracts the <spanx style="verb">&lt;session-string&gt;</spanx> from the request and finds the respective application TLS session object. The service decodes the received base64 encoded <spanx style="verb">records</spanx> and passes them to the TLS session. The session handles the TLS handshake message and will generates a full TLS handshake response flight where appropriate. For TLS1.2, this will include a Finished and ChangeCipherSpec message. For TLS1.3, there are not TLS records generated.</t>

<t><list style="symbols">
  <t>The service base64 encodes the TLS flight 2 response records and sends them in the response to the client</t>
</list></t>

<t>For TLS 1.2:</t>

<figure><artwork><![CDATA[
200 OK
Content-Type: application/atls

{
  "session": "<session-string>",
  "records": "<base64 encoded flight 2 response>"
}
]]></artwork></figure>

<t>For TLS1.3:</t>

<figure><artwork><![CDATA[
200 OK
Content-Type: application/atls

{
  "session": "<session-string>"
}
]]></artwork></figure>

<t><list style="symbols">
  <t>The client passes the service response to its TLS session</t>
</list></t>

<t>If there are TLS records included in the response from the service, the client decodes the received base64 encoded <spanx style="verb">records</spanx> and passes them to its TLS session.</t>

</section>
<section anchor="application-data-exchange" title="Application Data Exchange">

<t>Application data is exchanged between the client and service inside the TLS tunnel using exactly the same JSON transport payload. When the client has data to send to the service, it encrypts the data using the standard TLS stack methods (e.g. OpenSSL SSL_write() or Java SSLEngine.wrap()), extracts the encrypted TLS records from the bottom of the TLS stack, and sends them as in the JSON <spanx style="verb">records</spanx> parameter to the service. The service injects the TLS records into its stack and reads the decrypted data from the top of its stack.</t>

</section>
</section>
<section anchor="rtt-considerations" title="RTT Considerations">

<t>The number of RTTs that take place when establishing a TLS session depends on the version of TLS and what capabilities are enabled on the TLS software stack. For example, a 0-RTT exchange is possible with TLS1.3.</t>

<t>If applications wish to ensure a predictable number of RTTs when establishing an application layer TLS connection, this may be achieved by configuring the TLS softwrae stack appropriately. Relevant configuration parameters for OpenSSL and Java SunJSSE stacks are outlined in the appendix.</t>

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

<t>[[ TODO - New Content-Type must be registered. ]]</t>

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

<t>[[ TODO ]]</t>

</section>
<section anchor="appendix-a-tls-software-stack-configuration" title="Appendix A. TLS Software Stack Configuration">

<t>[[ EDITOR’S NOTE: We could include details here on how TLS stack configuration items control the number of round trips between the client and server.<vspace />
And just give two examples: OpenSSL and Java SunJSSE]]</t>

</section>
<section anchor="appendix-b-pseudo-code" title="Appendix B. Pseudo Code">

<t>This appendix gives both C and Java pseudo code illustrating how to inject and extract raw TLS records from a TLS software stack. Please not that this is illustrative, non-functional pseudo code that does not compile. Functioning proof-of-concept code is available on the following public respository [[ EDITOR’S NOTE: Add the URL here ]].</t>

<section anchor="b1-openssl" title="B.1 OpenSSL">

<t>OpenSSL provides a set of Basic Input/Output (BIO) APIs that can be used to build a custom transport layer for TLS connections. This appendix gives pseudo code on how BIO APIs could be used to build a client application that completes a TLS handshake and exchanges application data with a service.</t>

<figure><artwork><![CDATA[
char inbound[MAX];
char outbound[MAX];
int rx_bytes;
SSL_CTX *ctx = SSL_CTX_new();
SSL *ssl = SSL_new(ctx);

// Create in-memory BIOs and plug in to the SSL session
BOI* bio_in = BIO_new(BIO_s_mem());
BOI* bio_out = BIO_new(BIO_s_mem());
SSL_set_bio(ssl, bio_in, bio_out);

// We are a client
SSL_set_connect_state(ssl);

// Loop through TLS flights until we are done
do {
  // Calling SSL_do_handshake() will result in a full 
  // TLS flight being written to the BIO buffer
  SSL_do_handshake(ssl);

  // Read the client flight that the TLS session 
  // has written to memory
  BIO_read(bio_out, outbound, MAX);

  // POST the outbound bytes to the server using a suitable 
  // function. Lets assume that the server response will be
  // written to the 'inbound' buffer
  num_bytes = postTlsRecords(outbound, inbound);

  // Write the server flight to the memory BIO so the TLS session
  // can read it. The next call to SSL_do_handshake() will handle
  // this received server flight
  BIO_write(bio_in, inbound, num_bytes);

} while (!SSL_is_init_finished(ssl));

// Send a message to the server. Calling SSL_write() will run the
// plaintext through the TLS session and write the encrypted TLS
// records to the BIO buffer
SSL_write(ssl, "Hello World", strlen("Hello World"));

// Read the TLS records from the BIO buffer and
// POST them to the server
BIO_read(bio_out, outbound, MAX);
num_bytes = postTlsRecords(outbound, inbound);
]]></artwork></figure>

</section>
<section anchor="b2-java-jsse" title="B.2 Java JSSE">

<t>The Java SSLEngine class “enables secure communications using protocols such as the Secure Sockets Layer (SSL) or IETF RFC 2246 “Transport Layer Security” (TLS) protocols, but is transport independent”. This pseudo code illustrates how a server could use the SSLEngine class to handle an inbound client TLS flight and generate an outbound server TLS flight response.</t>

<figure><artwork><![CDATA[
SSLEngine sslEngine = SSLContext.getDefault().createSSLEngine();
sslEngine.setUseClientMode(false);
sslEngine.beginHandshake();

// Lets assume 'inbound' has been populated with
// the Client 1st Flight
ByteBuffer inbound;

// 'outbound' will be populated with the
// Server 1st Flight response
ByteBuffer outbound;

// SSLEngine handles one TLS Record per call to unwrap().
// Loop until the engine is finished unwrapping.
while (sslEngine.getHandshakeStatus() ==
       HandshakeStatus.NEED_UNWRAP) {
  SSLEngineResult res = sslEngine.unwrap(inbound, outbound);

  // SSLEngine may need additional tasks run
  if (res.getHandshakeStatus() == NEED_TASK) {
    Runnable run = sslEngine.getDelegatedTask();
    run.run();
  }
}

// The SSLEngine has now finished handling all inbound TLS Records.
// Check if it wants to generate outbound TLS Records. SSLEngine
// generates one TLS Record per call to wrap().
// Loop until the engine is finished wrapping.
while (sslEngine.getHandshakeStatus() ==
       HandshakeStatus.NEED_WRAP) {
  SSLEngineResult res = sslEngine.wrap(inbound, outbound);
  
  // SSLEngine may need additional tasks run
  if (res.getHandshakeStatus() == NEED_TASK) {
    Runnable run = sslEngine.getDelegatedTask();
    run.run();
  }
}

// outbound ByteBuffer now contains a complete server flight
// containing multiple TLS Records
// Rinse and repeat!
]]></artwork></figure>

</section>
</section>
<section anchor="appendix-c-example-atls-handshake" title="Appendix C. Example ATLS Handshake">

<t>[[ EDITOR’S NOTE: For completeness,  include a simple full TLS handshake showing the B64 encoded flights in JSON, along with the HTTP request/response/headers. And also the raw hex TLS records showing protocol bits ]]</t>

</section>


  </middle>

  <back>


    <references title='Informative References'>





<reference  anchor="RFC5246" target='https://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="I-D.ietf-tls-tls13">
<front>
<title>The Transport Layer Security (TLS) Protocol Version 1.3</title>

<author initials='E' surname='Rescorla' fullname='Eric Rescorla'>
    <organization />
</author>

<date month='July' day='3' year='2017' />

<abstract><t>This document specifies version 1.3 of the Transport Layer Security (TLS) protocol.  TLS allows client/server applications to communicate over the Internet in a way that is designed to prevent eavesdropping, tampering, and message forgery.</t></abstract>

</front>

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



<reference  anchor="RFC5705" target='https://www.rfc-editor.org/info/rfc5705'>
<front>
<title>Keying Material Exporters for Transport Layer Security (TLS)</title>
<author initials='E.' surname='Rescorla' fullname='E. Rescorla'><organization /></author>
<date year='2010' month='March' />
<abstract><t>A number of protocols wish to leverage Transport Layer Security (TLS) to perform key establishment but then use some of the keying material for their own purposes.  This document describes a general mechanism for allowing that.  [STANDARDS-TRACK]</t></abstract>
</front>
<seriesInfo name='RFC' value='5705'/>
<seriesInfo name='DOI' value='10.17487/RFC5705'/>
</reference>



<reference  anchor="RFC7516" target='https://www.rfc-editor.org/info/rfc7516'>
<front>
<title>JSON Web Encryption (JWE)</title>
<author initials='M.' surname='Jones' fullname='M. Jones'><organization /></author>
<author initials='J.' surname='Hildebrand' fullname='J. Hildebrand'><organization /></author>
<date year='2015' month='May' />
<abstract><t>JSON Web Encryption (JWE) represents encrypted content using JSON-based data structures.  Cryptographic algorithms and identifiers for use with this specification are described in the separate JSON Web Algorithms (JWA) specification and IANA registries defined by that specification.  Related digital signature and Message Authentication Code (MAC) capabilities are described in the separate JSON Web Signature (JWS) specification.</t></abstract>
</front>
<seriesInfo name='RFC' value='7516'/>
<seriesInfo name='DOI' value='10.17487/RFC7516'/>
</reference>



<reference  anchor="RFC8188" target='https://www.rfc-editor.org/info/rfc8188'>
<front>
<title>Encrypted Content-Encoding for HTTP</title>
<author initials='M.' surname='Thomson' fullname='M. Thomson'><organization /></author>
<date year='2017' month='June' />
<abstract><t>This memo introduces a content coding for HTTP that allows message payloads to be encrypted.</t></abstract>
</front>
<seriesInfo name='RFC' value='8188'/>
<seriesInfo name='DOI' value='10.17487/RFC8188'/>
</reference>




    </references>



  </back>

<!-- ##markdown-source:
H4sIAAqB91kAA9U9aXMbx5Xf51d06A+iTACyFOcoxtaGoqg1Y0tUkdQqVS6F
HmAaRFuDGWQOkihT+e37rr5mBrysbNYsUwZm+nj97vf6dXM8HidJY5pc76qt
vdUqN7O0MWUx/iFd60qd/nCylaTTaaUvdtUefEuyclakS2idVem8Gc8ro/Nx
k9fj8kJX40XTrMZffZXAIPq8rNa7qm6yJKmbtMjO0rwsoONa18nK7Kofm3I2
UnVZNZWe1/BpvcQPH5IkbZtFWe0mapwo+DFFvauOJuoVzkVPGIKjS10ED8vq
fFftm3pW0le9TE2+q0qC8K8zfD6Zlcto0OOJepFWBQDkRz02s0VaZeGL4ZGr
fPpXs7qY1FfRmK8n6m1lGvPRFMGor9Or+PHwmCtpEsCbjMdjlU7rpkpnTZIk
r9NirWa50UVTq0LrTDWl0oDhaW7qhar1rK20mpVFoWdIyRrfp56y0KK6MDNd
q2nbqHk6g8aLNM91cQ7P3ECmOFfNQtfxUFmrcTh4AaDCywJ6l3O1NFmW62l5
BSM0i7RRja6WpgAmQA6KRphX5ZL68xIUMIaqPPiFvux1kQkF7ok6XRiApJy1
Sxwg03MDhFKpWmpYSGHqpZqXlQJ8FfUKuAtXgkNWelZWWQ1UUt+dnr6F5nWd
nms1LTOD2NDNpQaGsqhFwCyqZE5dAJTQdKjJrVRoawsI4gfWE9IkR2kb0YAg
DSmiZd3HagpDmgJwO9MrWhascT43MztiAUsoq488mkphzqKp2rpBHrHYmKhD
YAEQr2YEfWBRHmtLEOGaBkIo4WFWL9KPWrUrenh0cgjSnM4+WoL0FjBJmFsZ
cPjyBUzWVGXWEg6S5HShYQm4jHlawXyIojyta5gWuMiidapxbZle5eUaQIfR
mzJL149qu0BCR6EETY1ZEjdemLKt87XQalXiqAFnI09YBKUZcKeBxTRlVavL
RekEaZlCY1ydCVojVRzH1o6qSIAybsskHJxb+P1CFxlOiu3kUV3Om0tESqYv
dF6utMC0BNIBz9XISSxVNJUDA1AgoJCI5zmw+D9bU+mAcZPkqEA+XC4Bjfoq
Xa5y4CEcnyhhQUCBCvCdqrycpTkIGailwiGCgFhVZQNTghzBL8AK2AeOFPZO
iXWs9OMTx8SjDh4J5R2xSfuCQ0uz60HZTVVm5nOAnoZgwC5MSiO7yYAJqjQz
OADgZS2svkiRuUDGWZAzNV1HcmPZokK+EISIHoQ2M9QXFeheDTpljowPCCRL
ZRoYRwStKkvAC8LtViocifSaQpfZwgCdM2TfGpCsBXVkI9HwNGWZi8AznCxs
EWyIlLYB6jQAByxQrVpAXweG1vGFYHyJc6OuNEW0btLJwAvQpkqBEDCEUB7o
APILbFzJIlj8kJ/xF1kVMYwMtmqB7GDG83TVlCuvHJGbq7YoojUeQU/mj5M1
gLyU9QqKBBBYFogjqOjMYtAuAx+S8gdmRLIocFBSgWvZ5o3JV4OaxWnRjooh
/YJMgkIBExWlBzW2KoCQuTlvK9a+fZLXTk04ft8wpLNTYSckGItAjiyVIvZ0
aAgmpERJytDhspbMgsjGMGMCh1aya7pQcQ0MzxhCe1wZUCuoN9pCdDx1ovms
2QHQ1yBUFyiXQGqyMwsgps4viMmakpFwm3fibGg6q8raqXnLhNOyRbwZWv0X
6pS0S5mX52tARoQIWDG4kLqqWJmDuO+RPlpUZXu+IIGIsGIm4E6Ebq/ybi/N
Rd1Pre1U/12mec0UWJjzhcpRYatzfAr+sLmwyiLTtTkvkPM6JhZ4bxdsJEDZ
AuL1FQi09QrqlZ6xWiG0/PLLfx2/2v/Ds6//+OkTfjkcv5wY3czJ14bfp7+H
57BAlEnT0NpY+5MaBrOIerqclTnaITRCMCshFVuTUkDi01QAJnr2Y8ALsKkd
R9Mo0hmxCZQjpUvAWpNFDkHt+y6RxRuiMOoqU7BkLMpL51iwD2FqJ0toc9CA
6AzGAfEHqbhEMUGlAthADUhAz9sGmQfHsLBHi5qW8A/xATIdfjjxfg+0TC9K
g6LBHonFu8MTOjw5PgXOAuYGkGrwygvQsMzLtAAevuv4MCNFo30sykswMeea
gOEhyQTBJN7yOHyMHAP/jFYfjFy7nEbQO0cgcp1Zw3p6GDTwyNvCRvgMuKSm
5/gJfJMaUUrcXYE9QGOOAx9doBTqS3jxhXojEhi2SJI91axXaHC8hJIGXYoL
YfK8JQvFGugVEVc9BZezQZfzsvYOR+xDeQOPljwN7Th0BekqXf/Qv3BGmucD
MwYjk9BF0YJDmNNDFC445AoN47CDWSpyKtT2/vj5a2z3eNR5g/q2rUDiV7q4
z9j3XI3afj1+fkoQRAtDuwkKp7RCG3goF2DQM2ZV0Ivs7oIHZBwJXHwVID2M
j5iH3IJQWJHjSLHx4mzk1GHNiAqvjDhifdlBHERz6SvWOoiG2mTaC14nZAMs
QUSnq44Tif5dNm7KMfyPJQy64Xy3A0okPmEEJ8m//vUvCs7hZ2fsfnbUwDPb
7lqBNVEv0yaFjwPP7jqeunkSC2U4Sf/Zv2NmxZRQ4cz9ZxE4n2/Nr7trtuIQ
zezB+WxrPt1/az9ufBY9/HUzJzudBsHboUfBc/94JwGcMZdf04PngC+nsdwj
8nC8CrqWxyciENefCRb4+g/18J9/JBGq7/9DFOnAKdgB7WFXi8jYd3o6XhKp
g1921Rdg/MYpGEZFedNvt4aM5dYnRYY09C1jYzrgRqFbBo5SqCKDlACA+agt
Vnl7/kiczHkKsY6zxXU5+6ibnunhBFua0YdLiFV1lA3LwNObNRBtUBA4XcPr
aYvxdTfptRmqGWasBtJBoe6FcEhfUQqTYK/SywAKmjZIDYIjB7GttX2Bj8T5
Mbs+jpy4L9kktH11axoOmn3Gy0ZMXXSj2TzXBYaiPA68gLUsySWet+AjY695
Dq5+g3bTAM2X6RrszixvwS5RqIl+VYBQwdpGb+gZWCEgcmxdop+ISXdubgFy
9Z3L0x0LSWM5ub65xXXSlV2Wf/jBVVGTjS28ZPXlbeOX4OELxDmN8K7Qxaxa
rxBZZK/o/YklGHw56L6/4ypck+EWL5jZb1jFCcUrN6zC4+FGGOnL8Dp/9SoC
GAZ+dtR9OMqqOQw0KdtMewSi65AnGCGH9lVNuu6UhLEvZWrv7aFVIjfokGlr
cvHEbPc0jE6Ghen3LNvhsKyMOP1E0Kfo4nLQW9ysoyJ/0ukFStSCAmuXXbVV
92d3SqcW7dTpYT3aIW/WZlBdmogaERJ5Iv9dtBDHHJRJMJho4rRQRU5IoCZL
jKQ5jaN96LHSnNS7RXHT+uONhfAtZeww7sZUSIWrgQUsgHzZyGad+zwhOjJI
ocS0dsaG9HjJEwzuy7AWjc36jkpiSYVvYIb7D0X+Yo8pNNjX34QShq60SGvc
pTOsqE3yBunjtR1Bvva6WLWMXhej9VpGEN0TdNmhwSLA3MwbALt2/3Rl3T37
x8bWQz/X/dZ/Ozl6E4y9E080+KgP4dt0nZfgqVyLA28H9wk4/2j/7ZPDt+pm
1DD2BP2kuSx65ZEb97rHQ11s3W1FVncC/44jnhb1uckdHHYXIcaW7i9AG81N
U4dbaDVJXA7+BL9DSenpkAGF3A2W++LvsrRR9heD8kLnLopOwxg6jRIutbY+
EmU7C7+/xglqaI4bvWQIy/MqXYFrBU/Oy8YwHJQ1ljSAz6lNdbBDGyoCTO5F
2yGCE3YpaSqzQgWJ3iHu9a45I7ZW7eocN4okb9vHVjzywMBzMDeALPBvp+35
3FzhJ93MJqieB5DP8+maqH0YJeuS5G2t2wy1dRYYPISN0qflw9x44QnSoUcr
XZyc/EBj/C29SEFsTw5Q356bC13YbSFgCF1kol8lB+6zg2QxajCHK6KUsTv+
PqdyCbBHm3rdkCTe3bPpF817So7s4INHeSg2Vm0BBjpfy+73pmFnZQvuxFRz
XID2sCS7FWXNCM4Gs2G3yMOm7J1ADdwkQHdLDboth6w/Ztth/tpWQqxA1hjz
X3TCUWCaQw6J7oYEIA0M4Lb50+JWUoGVBxgzjfS3qf5gr4aEuUTx5UG6c3OE
5HDveDJCA4bZtJEmrdg189nHeIo+MXgSAnyqe0MnyR5iUpXAnUtTU8eR8x3Q
bZotyrImt6IsUAHAZ+LwFPO2c9AeU3Kw3JaNmW/Kp85Tk7ut3lsyvt0alle8
86dWbcXVAsDtUe3N0FZ4d7GjkJRZqWvagrGqFlxrkKdlLyM8W2gMfgGAYC13
WgUw5QlgNU8r3lL3BEXEUpr+/46XZNn/BlbikbFyYqY39OxQ10jhFPDDAj3f
AD7ETKWtIx7izBqcgDYioFycwQVWTb9MYRCEqd3cNHGqxm4rwgoXKZbIcEao
bBuXWq9nEIa5zcpoH5LV0FtrgONqnj3AWzhVqPm6ewZYeZHW+o9fQyiI9i1T
K3b2XEhEHmQnJPI7u0E25yAFoklvKlBIDe25dBI2gPmMapdgYcgFpRQchfEb
WzNbhgOMSim4jYuKjRVYyyGY4fHbo5NTp9dlErtR5yYZGNgW42wc+NlXX6mj
772VsB27E74pow1YJMYqh1A9s3IORqWBqU7XK21RCC9RAkxHEeisH/GGoJNK
5RF8yVi0zXMGKiaFJznwOYkrmfcz9sjOkN0CEw8GDr2qEL5obygocBjYDh5J
1O3U0TReCbtCxObWqZw4o2rJChNJ3MmbtTeoAB/Vk7ObWQ9KSDEKx03zy3Rd
C+2sb5BaknK6gkapSWNv4kGZIeCNNRNFprFmYCTOFFV8jUBesNKj6RDPJjlI
xWAIMeCx4jBgUPeQfC91PavMyrnoadNo8AO5cG7FiOXtXJuFJeGljUfHteTf
xlJBlriLmaIsxoIdu1qwxantw4OWMyxLkHRPw4U2uB+6otlB9N2u/mYqek9s
pg1WZnVqVL0vZuNHCBxnH2FQvwhU6K6gDfPcH3122MYrN+bHAe2s/E0jlX1Y
dZV23HwH4oYiVmfDYLKqXFXGDiDT0H46sQjRaiq5bFoUIAu3Tq8QStP4pBha
bzAIrPFw7K5yWjOC3nFogwh4r6e8G8EIIkhDW3X7PixK8FTbcImredSlHRYZ
wdY6usI0dAJkA8XyCNUWUXRK1jJHx8/JZln1BE00Vb0uZouqLKieNFbOE/Wm
bKQcU6q3ANafuQYQMIju5AwMXW2ryax3EcTAWCQQrWYDPqyzSNi1O1T7oq0r
tTcHVQjTgiEequ4mC8zlGrCIDEsHDTgJaIu5ysrzpx2SxejCVE2b5q5acKL2
WDGgcwChqgZDO0I2pfpUWBpXpmSMlBrRW8y0LSuK1bctfwnYE4PqdUT7oKik
yxb6CpxiLmbAaEtTSWc6oxpAqXX0hZoELDAtesHszbi9GeHyHIl2N08IPZjG
5V4c7i41TGmNkgsauBKRkt7W4DAVv9cUtL0GwGDxuTq4kgp1FJTelM6lF14n
ngW3kMwEGxfkN4BXqsX+9NUfPn2aqPeLjcwUsjvW/DZUPWyjwr0oGx6cBrBO
bSgsKKKtGJWPGmNgsrIQxbeF1PZ1d/A4A1SBBpMkMXbslt5HvB/G6+EycHIK
3QWCOh6xm+MKA5E464TMr6+aOOOEesDm0sI9RR8V1i04ocASpAtB3dmtH0QM
E+NPf3iKpXtAMb8rJG7N+AB9YBwd2YS0I/f589M//xkIiFkX53O/1A3GmcQ+
r0XpvgCly/53R/8jbxJI8l1EG6cSHxjDMnAGUqraxiiMUpaJUltC961dtfWN
fB6j0ijOn2+NFLYQK0QtOt58YKSebyWfaFTS/fMSVTJJQTRz6M0BFDLhLkxj
ZbRGzRhrBrLyNZUK8rZGVekchdwnUbq6zfr2bGXt4QALBu3TBs5b6lGKYVRa
Nd4ZmJsK9B3/a9GOAVrvSEs31md5TOM4w48osPd4NhJG8Ylc4A/q9/U7cPrL
pZG4z61pYuezWGOlOzSlLfxmwLZZ26b+PRkvu9tNcQO1/A6UXvl41NPOfu+N
t96wMjxcRDn9GdSNB77StIFlzfXYu6M/dTnwp64ZDvQCjeWhBPgHugtx63bK
FqrxdI7COgpBwkUhvxU2IgB2td6EXRQXrltODFywoTVQ/bljBFb24itYnyXE
zNfPnql3hRS5EwwH4Is14HAplYi4OZGJmNqKSFQt0Q3BoxC0kxncaDMAtAoP
MDi2N5VX8EPyVUtMaw+okJzeJjOdYVDdc26LjbuhVHxnaAkvHF3dHC7jEofZ
MZ3RkwAnrROWo7AG5zcWlBu30ghtn05+78NeIguoadLoVtdjDIulsxjW9l7w
wRurBFFphm93Q8w/SZu83vm5LgtWrjCP1C8dC1KTJFY0i37SZWB1Uf0tyWZP
6v3hKh+ADItYFPyiC5Sjf+J0FDA7OOnWbwZuX4tC8ofNhHojYUDRMN6KBNoy
oJ4gj/IghKg74fHfZffEXQe+PbaZGkebkN1EsPnYxHCcF2toxAl29IqyQ9BK
ryRH6ik5iMRVN7ARDHLA/R/F3mlPF1JegIWOvJh5Zzno6Lc15RXQo+E17Ca7
YV7kMvV5HXDeEO+YMFwHmRHLWnSEj0mTdAnDTuFwqgT8tq9h6hdpZkXSwsAo
flS7KTKTcaJCMmcpe21sIP0Cq2VijQSYnWl5gcHgJqMQTxakj9ONpii2c4m3
c96z4nYlpwbC4yqSUECV50PiNKQFrkMSOC6SMbix6Mdl7CZRbgBnsHvBmvw9
SvWM55VGZ4oSUSQ7WTvjzBUOYeNstpw+FTfAajhIN5WayH6wha9vEOsFZRhg
3gsbLlqmkDkSpwDFEgHaHKcIg9j9VJtJOrAe35K2HDgIFFRklG2b8mEFOXgR
OYU67KzmXFb4hczgq/5s1HAiobl6BS273jn2xtRs5Y5qFMEe9IUOXF4ZhXpY
Xc5qPD43LHn4W+oFhkp4+j87A0XG3SaduhqxjmHdSlzYIoQg9eBLW4LyGPkN
P0WQDDewkEi1j7Jl+PzJVbaERS5hg7BMKCwH2nE1J66wJfoYN7Adk361z3W3
rmXnxgauEn5DRef14NPo4239ERHbJ48f2j8o47mt/z6XKkf9v3ELfX5rf4vX
B63fTzQePxR/QG4sg3og/r1O+E/B72qKH9Tf1S9TsdjsI+qju/cPwH/uS9Ye
yL8Rz5Dfqbi+97JKV3fo3x8pggrPuzhevbv8hUN5Xn2Q/AZDPVT+bSXkw/r7
YvXfEPyWKx8Mv6O/l7bh/pbT4LH4MnGnoO2w/Fn+D8T6HvL3zUCf35T+uH//
jv64R3+Ja4wL+TACA+mmG1oMFaEFfhOee851gzsvytagJEEMNt5Ug4L1gRTW
zdKqGtjZSoIcP3k96OOv8SaPoStd7B4abUpCcJA3Zsn7NeS6yZZq9U+NEc0E
k1DUECJ3KScMZ4IBqGiQs1JTV9Zkt/YwrOocEICwdVUa2n699ajMzuDD3tE1
IQwB1iWclHcHh+bC1+Imxn3sw8F5boOtyztD/BSwkH0Vu/a3NlfbaJuegIZ4
fOvooXz22Hx49PvAHu5Scun9/WEfGGMz7P1naAtIFjFK4o0VYMA4XIKXX1oW
CA+M31BoSZkJV4BIct5tHZ2X0OHGWr9E9XAuz7h48/YKvw31iVLrE+sJTqzR
+ZG7Hhg3c9QQNPvNM04C1AV7Ad1Slng7IKrBGjzJM9DJaiVCB90PwjmKdec0
ZLRPgLvlJhjSa1zBlCuS4IoCw1llPGNpPCotIJKDC0vH49OMWF/gi9KCsJj3
kSg4DqfCu4HCDRYbcYclB80wqhxn2OoNUNJ4AYW6dJ04oRdtyUbgppUm8gX4
ipJ1/mIwCeuf+lo/ydRSkyXf0USxLbnFcaL2nnlaSTLekEK00DzfUjaB+KXL
+0WbUhH1kDpRaZDNzHVKesowFeRu8vlJhunmvPmw2F053yZC7O7yQJaOrxzi
XJxwZlgn4QnjEsYd9PwkqPuJs5p8IxKRSegSFQedeiGIdg1jBraZIBzRZqLr
YV53qTDH7rYiRcrSPeezMWXOJ8Rk9v6u/tTBTU5B+Z9ye/xcX83bM7b+PTi3
m+J1FKx8N8jYwM7X5xYyO8XtUiYo3Cxu3aSj1xIxN0cbpZiZDDZcLUdP7rEP
cJctgDuKr4Pf7wNEushzrlvNYJqVp49sym9ATGqYvcickHSNQpdbR2o/vIMO
egbf/0dXZr72khKUyo1+vWDdy0Q8e6CJ2Ly3P6gkTTNQuhmnl+9rcH7VrpZd
fZeVLeMGvCyr7Aovfkd37UL3udqXwjV8tnkDVhwmQtuE9Qt1d4qbrdT/P5tD
gnE/w2Pvu/Rlh4GJeBbaogEbQQJGhWH7VLN+EpSsdy2NLRBEOzFYaX1P/f/s
1+p/AU/BMu+zxfv5VPuzAdXucfaZYfostoMLgISQN5f5WybraJ04bPu1ItMB
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

-->

</rfc>

