<html><body><p><font size="2">Btw Helge, really interesting about the GCD channel APIs. How would your propose they be integrated? Would they replace or modify onSend/onReceive methods?</font><br><br><font size="2">gelareh</font><br><br><img width="16" height="16" src="cid:1__=8FBB0A7FDFC5505D8f9e8a93df938690918c8FB@" border="0" alt="Inactive hide details for Gelareh Taban via swift-server-dev ---03/23/2017 09:46:49 AM---Hi Helge, &gt; My headache with the desig"><font size="2" color="#424282">Gelareh Taban via swift-server-dev ---03/23/2017 09:46:49 AM---Hi Helge, &gt; My headache with the design is that it doesn’t support async I/O</font><br><br><font size="2" color="#5F5F5F">From:        </font><font size="2">Gelareh Taban via swift-server-dev &lt;swift-server-dev@swift.org&gt;</font><br><font size="2" color="#5F5F5F">To:        </font><font size="2">Helge Heß &lt;me@helgehess.eu&gt;</font><br><font size="2" color="#5F5F5F">Cc:        </font><font size="2">swift-server-dev &lt;swift-server-dev@swift.org&gt;</font><br><font size="2" color="#5F5F5F">Date:        </font><font size="2">03/23/2017 09:46 AM</font><br><font size="2" color="#5F5F5F">Subject:        </font><font size="2">Re: [swift-server-dev] Draft proposal for TLS Service APIs (please        review)</font><br><font size="2" color="#5F5F5F">Sent by:        </font><font size="2">swift-server-dev-bounces@swift.org</font><br><hr width="100%" size="2" align="left" noshade style="color:#8091A5; "><br><br><br><font size="2">Hi Helge,</font><br><font size="2"><br>&gt; My headache with the design is that it doesn’t support async I/O <br>&gt; (even if you don’t implement that right away, you could still design the API to support it). <br>&gt; For read/write I would propose to match the GCD channel API.</font><br><font size="2"><br>Regarding I/O, current design of TLSService lets the implementation of onReceive/onSend handle both blocking/non-blocking I/O. This is essentially the model of SecureTransport and OpenSSL: if they receive less data than expected and know that requested I/O hasn't completed, they return errSSLWouldBlock or SSL_ERROR_WANT_READ/WRITE errors and let the caller handle them appropriately. So TLSService would follow the same idea and when implementing onReceive/onSend which handles the data, would return EAGAIN and let the caller decide what to do if appropriate. The caller layer (or layers above it) is the one that decides what I/O should be configured.</font><br><font size="2"><br>Regards,<br>gelareh</font><br><br><br><br><img src="cid:1__=8FBB0A7FDFC5505D8f9e8a93df938690918c8FB@" width="16" height="16" alt="Inactive hide details for Helge Heß via swift-server-dev ---03/23/2017 06:25:51 AM---On 23 Mar 2017, at 12:11, Michael Chiu via"><font size="2" color="#424282">Helge Heß via swift-server-dev ---03/23/2017 06:25:51 AM---On 23 Mar 2017, at 12:11, Michael Chiu via swift-server-dev &lt;swift-server-dev@swift.org&gt; wrote: &gt; Hi</font><br><font size="2" color="#5F5F5F"><br>From: </font><font size="2">Helge Heß via swift-server-dev &lt;swift-server-dev@swift.org&gt;</font><font size="2" color="#5F5F5F"><br>To: </font><font size="2">swift-server-dev &lt;swift-server-dev@swift.org&gt;</font><font size="2" color="#5F5F5F"><br>Date: </font><font size="2">03/23/2017 06:25 AM</font><font size="2" color="#5F5F5F"><br>Subject: </font><font size="2">Re: [swift-server-dev] Draft proposal for TLS Service APIs (please review)</font><font size="2" color="#5F5F5F"><br>Sent by: </font><font size="2">swift-server-dev-bounces@swift.org</font><br><hr width="100%" size="2" align="left" noshade><br><br><tt><font size="2"><br>On 23 Mar 2017, at 12:11, Michael Chiu via swift-server-dev &lt;swift-server-dev@swift.org&gt; wrote:<br>&gt; Hi Gelareh,<br>&gt; <br>&gt; I haven’t attended a single security API meeting yet but just curious if it is possible to make the api support vector write or write from swift Collection protocol?<br><br>The disadvantage of Collection over Array (or UnsafePointer) is that there is not standardised way to quickly get a raw pointer to it, right? How would you efficiently grab the data, by iterating over the Collection? :-)<br><br>Also, what you propose doesn’t actually work in Swift 3.0. Does it work in 3.1 or 4? (`error: cannot specialize non-generic type ‘Collection’`)<br><br>&gt; Like the followings:<br>&gt; func tlsWrite(buffer: Collection&lt;UInt8&gt;) throws<br>&gt; func tlsWritev(vectors: Collection&lt;iovec&gt;)<br>&gt; <br>&gt; If it is possible it will be very helpful since <br>&gt; 1) it is very swifty and user friendly<br>&gt; 2) vectorIO could significantly reduce the overhead to merge fragments of bytes into a single buffer.<br><br>+1 on vectors.<br><br>My headache with the design is that it doesn’t support async I/O (even if you don’t implement that right away, you could still design the API to support it). For read/write I would propose to match the GCD channel API.<br><br>hh<br><br>&gt; <br>&gt; Michael.<br>&gt;&gt; On Mar 20, 2017, at 1:04 PM, Gelareh Taban via swift-server-dev &lt;swift-server-dev@swift.org&gt; wrote:<br>&gt;&gt; <br>&gt;&gt; Hello all,<br>&gt;&gt; <br>&gt;&gt; I would like to share the following API proposal draft for Server security. Once enough feedback has been received, I will initiate a PR for an official review period.<br>&gt;&gt; <br>&gt;&gt; A more readable version of the proposal can be found at: </font></tt><a href="https://github.com/gtaban/blogs/blob/master/TLSService_API_Proposal.md"><tt><u><font size="2" color="#0000FF">https://github.com/gtaban/blogs/blob/master/TLSService_API_Proposal.md</font></u></tt></a><tt><font size="2">&nbsp;<br>&gt;&gt; <br>&gt;&gt; Regards,<br>&gt;&gt; Gelareh<br>&gt;&gt; <br>&gt;&gt; <br>&gt;&gt; ------------------------------------------<br>&gt;&gt; <br>&gt;&gt; Proposal: SS-001 (TLS Service APIs)<br>&gt;&gt; Authors: Gelareh Taban, Bill Abt<br>&gt;&gt; Review Manager: TBD<br>&gt;&gt; Status: Awaiting review<br>&gt;&gt; <br>&gt;&gt; 1 - Introduction<br>&gt;&gt; <br>&gt;&gt; This proposal presents the design of TLS service, which is a collection of Swift APIs that provide SSL/TLS functionality with a consistent API surface for both Apple and Linux platforms.<br>&gt;&gt; <br>&gt;&gt; For the purposes of brevity, we use the term TLS to refer to all SSL and TLS related functionality in the remainder of the document.<br>&gt;&gt; <br>&gt;&gt; 2 - Motivation<br>&gt;&gt; <br>&gt;&gt; Currently there is no standard set of Swift TLS APIs on Apple and Linux platforms which has resulted in projects implementing their own Swift security functionality or using their security library of choice (be it OpenSSL, LibreSSL, etc.). This has resulted in fragmentation of the space as well as incompatibility of project dependencies if more than one security package is needed by different modules.<br>&gt;&gt; <br>&gt;&gt; This motivates the necessity for defining a standard set of protocols that define the behavior of the TLS service and how the application and the server and networking layers beneath it interact with the TLS service.<br>&gt;&gt; <br>&gt;&gt; 3 - Proposed solution<br>&gt;&gt; <br>&gt;&gt; We propose a new model that is easily extensible and supports a plug-n-play architecture which allows an application to choose the underlying security framework of choice.<br>&gt;&gt; <br>&gt;&gt; </font></tt><a href="https://github.com/gtaban/blogs/blob/master/TLSServiceArchitecture.png"><tt><u><font size="2" color="#0000FF">https://github.com/gtaban/blogs/blob/master/TLSServiceArchitecture.png</font></u></tt></a><tt><font size="2"><br>&gt;&gt; <br>&gt;&gt; 3.1 - Assumptions<br>&gt;&gt; <br>&gt;&gt; At the time of writing this proposal, the Swift Server API work group has not yet defined any standards for the transport management or application layers. For our design, we have assumed a network stack that consists of:<br>&gt;&gt; <br>&gt;&gt; - System transport layer<br>&gt;&gt; - Transport management<br>&gt;&gt; - HTTP request management<br>&gt;&gt; - (Optional) Web server<br>&gt;&gt; - Application<br>&gt;&gt; <br>&gt;&gt; <br>&gt;&gt; Our security stack is composed of:<br>&gt;&gt; - Underlying security framework (SecureTransport library in Security.Framework on Apple and OpenSSL or alternatives on Linux)<br>&gt;&gt; - TLS service<br>&gt;&gt; <br>&gt;&gt; <br>&gt;&gt; In our model diagram (</font></tt><a href="https://github.com/gtaban/blogs/blob/master/TLSServiceArchitecture.png"><tt><u><font size="2" color="#0000FF">https://github.com/gtaban/blogs/blob/master/TLSServiceArchitecture.png</font></u></tt></a><tt><font size="2">) we omit both the system level transport layer as well as the underlying security library and show the relationship between the TLS service protocol and the various application layers.<br>&gt;&gt; <br>&gt;&gt; <br>&gt;&gt; 3.2 - Design description<br>&gt;&gt; <br>&gt;&gt; TLS service protocol defines a set of methods that is implemented by TLS service and it interfaces with the transport management layer (for example, socket management). These methods are implemented by the TLS service which in turn uses its choice an of underlying security library. As an example, the TLS service uses SecurityTransport library on Apple platform and OpenSSL or alternatively LibreSSL on Linux.<br>&gt;&gt; <br>&gt;&gt; If an application requires TLS for its use case, it creates a TLS service object and configures it based on its requirements. Note that the configuration of the TLS service is outside the scope of the current document.<br>&gt;&gt; <br>&gt;&gt; The application then passes the TLS service object to its lower level frameworks that deal with networking and communication. Each lower level framework maintains an optional instance variable of type TLS service protocol. If the optional variable exists, it is further passed down until it gets to the lowest level that deals with the Swift transport layer APIs (in the diagram above, this is the HTTP Management layer). When this layer creates the connection using the transport layer APIs, it assigns the TLS service object to the transport layer delegate. The Swift socket layer is then responsible for calling the TLS service protocol methods that handle the TLS functionality at the appropriate times.<br>&gt;&gt; <br>&gt;&gt; Note that in the diagram above, we abstract away the transport mechanism using transport management protocol. The definition for this protocol is out of the scope of this proposal and will be discussed in a separate, future proposal.<br>&gt;&gt; <br>&gt;&gt; <br>&gt;&gt; 3.3. - Benefits<br>&gt;&gt; <br>&gt;&gt; There are several benefits provided by this model:<br>&gt;&gt; <br>&gt;&gt; 1- It allows the application to choose the underlying security library of choice for their TLS by passing in the appropriate TLS service object.<br>&gt;&gt; <br>&gt;&gt; As long as the TLS service object conforms to the specification of the TLS service protocol, it can implement its methods using any underlying security library. The application can then create the TLS service object of its choice and simply pass the object to the appropriate methods that invoke transport-level functionality.<br>&gt;&gt; <br>&gt;&gt; This model is specially important for projects that involve multiple dependencies that use conflicting security libraries (e.g., LibreSSL and OpenSSL which share the same API surface and building a project with both of these libraries results in link errors). Now the application can choose its own TLS service object and pass it to all frameworks that require TLS.<br>&gt;&gt; <br>&gt;&gt; 2- Application do not have dependency on underlying security framework if TLS is not enabled.<br>&gt;&gt; <br>&gt;&gt; By mandating Transport/HTTP Management layers to be dependent only on the TLS service protocol, they are agnostic of the underlying security framework and hence do not need to have them in the project if they are not used.<br>&gt;&gt; <br>&gt;&gt; 3- It allows users to use the same TLS library for both client and server applications.<br>&gt;&gt; <br>&gt;&gt; This is especially important for many server side applications which need to behave as both clients and servers depending on external services they connect to. Also by decoupling the TLS service client and server objects, debugging an application with multiple types of connections will be simplified.<br>&gt;&gt; <br>&gt;&gt; 4- The underlying Transport/HTTP Management layers are agnostic of the underlying security functionality and simply hand off the TLS service object to the Transport layer delegate.<br>&gt;&gt; <br>&gt;&gt; 5- The underlying Transport layer is responsible for supporting blocking and non-blocking connections as long as the underlying security library supports both types of connection.<br>&gt;&gt; <br>&gt;&gt; <br>&gt;&gt; 3.4 - A note on creating a Swifty TLS service<br>&gt;&gt; <br>&gt;&gt; There are a number of cases in low-level systems programming where similar functionality is differentiated by a flag or type, such as SOCK_STREAM vs. SOCK_DGRAM or SSLv23_server_method vs. SSLv23_client_method.<br>&gt;&gt; <br>&gt;&gt; The latter is an example of how OpenSSL differentiates between the server side or the client side of a TLS connection. In TLS, the client is the initiator of a TLS session; the server is the entity that accepts the requests for TLS sessions made by clients. Depending on the connection type (server or client), different actions and policies are supported such as cipher suite selection during a TLS handshake, request for handshake renegotiations and trust validation policies for server name and certificates.<br>&gt;&gt; <br>&gt;&gt; Whilst using a flag or a type is convenient in languages such as C, it's not very Swift-like and does not adhere to the single responsibility principle [1] of object oriented paradigm. We recommend that different interfaces should be created that decouple the client and server concepts as far as the higher application layers are concerned. This is generalized approach that can be adopted by the other layers of the application stack. For example, the Transport layer can also decouple the interface of client and server connections.<br>&gt;&gt; <br>&gt;&gt; 4 - Detailed design<br>&gt;&gt; <br>&gt;&gt; 4.1 - TLS service protocol<br>&gt;&gt; <br>&gt;&gt; The TLS service protocol describes the methods that the transport layer calls to handle transport-level events for the TLS service object.<br>&gt;&gt; <br>&gt;&gt; - onClientCreate<br>&gt;&gt; <br>&gt;&gt; This will be called when a client I/O connection is created and appropriate TLS connection needs to be configured, including context creation, the handshake and connection verification.<br>&gt;&gt; <br>&gt;&gt; This is a client only method.<br>&gt;&gt; <br>&gt;&gt; ///<br>&gt;&gt; /// Setup the contexts and process the TLSService configurations (certificates, etc)<br>&gt;&gt; ///<br>&gt;&gt; <br>&gt;&gt; func onClientCreate() throws<br>&gt;&gt; <br>&gt;&gt; - onServerCreate<br>&gt;&gt; <br>&gt;&gt; This will be called when a server I/O connection is created and appropriate TLS connection needs to be setup, including context creation, the handshake and connection verification.<br>&gt;&gt; <br>&gt;&gt; This is a server only method.<br>&gt;&gt; <br>&gt;&gt; ///<br>&gt;&gt; /// Setup the contexts and process the TLSService configurations (certificates, etc)<br>&gt;&gt; ///<br>&gt;&gt; <br>&gt;&gt; func onServerCreate() throws<br>&gt;&gt; <br>&gt;&gt; - onDestroy<br>&gt;&gt; <br>&gt;&gt; This will be called when an I/O instance connection is closed and any remaining TLS context needs to be destroyed.<br>&gt;&gt; <br>&gt;&gt; This is both a client and server method.<br>&gt;&gt; <br>&gt;&gt; ///<br>&gt;&gt; /// Destroy any remaining contexts <br>&gt;&gt; ///<br>&gt;&gt; func onDestroy()<br>&gt;&gt; <br>&gt;&gt; - onAccept<br>&gt;&gt; <br>&gt;&gt; This will be called once an I/O instance connection has been accepted, to setup the TLS connection, do the handshake and connection verification.<br>&gt;&gt; <br>&gt;&gt; This is both a client and server method.<br>&gt;&gt; <br>&gt;&gt; ///<br>&gt;&gt; /// Processing on acceptance from a listening connection<br>&gt;&gt; /// <br>&gt;&gt; ///<br>&gt;&gt; /// - Parameter IORef: The connected I/O instance<br>&gt;&gt; ///<br>&gt;&gt; func onAccept(IORef: TransportManagementDelegate) throws<br>&gt;&gt; <br>&gt;&gt; - onConnect<br>&gt;&gt; <br>&gt;&gt; This will be called once a socket connection has been made, to setup the TLS connection, do the handshake and connection verification.<br>&gt;&gt; <br>&gt;&gt; This is both a client and server method.<br>&gt;&gt; <br>&gt;&gt; ///<br>&gt;&gt; /// Processing on connection to a listening connection<br>&gt;&gt; ///<br>&gt;&gt; /// - Parameter connectionRef: The connected I/O instance<br>&gt;&gt; ///<br>&gt;&gt; func onConnect(IORef: TransportManagementDelegate) throws<br>&gt;&gt; <br>&gt;&gt; - onSend<br>&gt;&gt; <br>&gt;&gt; This will be called when data is to be written to an I/O instance. The input data buffer is written to the TLS connection associated with that I/O instance.<br>&gt;&gt; <br>&gt;&gt; This is both a client and server method.<br>&gt;&gt; <br>&gt;&gt; ///<br>&gt;&gt; /// Low level writer<br>&gt;&gt; ///<br>&gt;&gt; /// - Parameters:<br>&gt;&gt; /// - buffer: Buffer pointer<br>&gt;&gt; /// - bufSize: Size of the buffer<br>&gt;&gt; ///<br>&gt;&gt; /// - Returns the number of bytes written. Zero indicates TLS shutdown, less than zero indicates error.<br>&gt;&gt; ///<br>&gt;&gt; func onSend(buffer: UnsafeRawPointer, bufSize: Int) throws -&gt; Int<br>&gt;&gt; <br>&gt;&gt; - onReceive<br>&gt;&gt; <br>&gt;&gt; This will be called when data is to be read from an I/O instance. Encrypted data is read from TLS connection associated with that I/O instance and decrypted and written to the buffer passed in.<br>&gt;&gt; <br>&gt;&gt; This is both a client and server method.<br>&gt;&gt; <br>&gt;&gt; ///<br>&gt;&gt; /// Low level reader<br>&gt;&gt; ///<br>&gt;&gt; /// - Parameters:<br>&gt;&gt; /// - buffer: Buffer pointer<br>&gt;&gt; /// - bufSize: Size of the buffer<br>&gt;&gt; ///<br>&gt;&gt; /// - Returns the number of bytes read. Zero indicates TLS shutdown, less than zero indicates error.<br>&gt;&gt; ///<br>&gt;&gt; func onReceive(buffer: UnsafeMutableRawPointer, bufSize: Int) throws -&gt; Int<br>&gt;&gt; <br>&gt;&gt; <br>&gt;&gt; 5 - Non-goals<br>&gt;&gt; <br>&gt;&gt; This proposal:<br>&gt;&gt; <br>&gt;&gt; 1- DOES NOT describe the TLS service configuration, which includes information on certificate types, formats and chains, cipher suites, etc. We expect this to be specified in a future proposal.<br>&gt;&gt; <br>&gt;&gt; 2- DOES NOT describe the TLS service trust policies, which define trust and validation policies of the incoming connection. We expect this to be specified in a future proposal.<br>&gt;&gt; <br>&gt;&gt; 3- DOES NOT describe the interface between the TLS service and the transport layer and any dependencies. We expect this to be specified in a future proposal.<br>&gt;&gt; <br>&gt;&gt; <br>&gt;&gt; 6 - Source compatibility<br>&gt;&gt; <br>&gt;&gt; The proposed change is designed to be as non-breaking as possible, however it does place several assumptions on the rest of the transport/application stack.<br>&gt;&gt; <br>&gt;&gt; - The application layer must import and instantiate a TLS service object which implements the TLS service protocol if it wants to enable TLS service.<br>&gt;&gt; <br>&gt;&gt; - Every framework layer above the transport management layer but below the application layer (which includes HTTP and server frameworks) has an optional object that implements the TLS service protocol. If the TLS object exists, it is passed down to each layer below.<br>&gt;&gt; <br>&gt;&gt; - The HTTP layer which sets up the transport management layer assigns the TLS object to the transport management delegate if the object exists.<br>&gt;&gt; <br>&gt;&gt; - The transport management layer which sets up the I/O communication implements the transport management protocol.<br>&gt;&gt; <br>&gt;&gt; - The transport management layer which sets up the I/O communication and deals with the low level C system I/O, calls the appropriate TLS service protocol methods whenever I/O data needs to be secured.<br>&gt;&gt; <br>&gt;&gt; - The long term goal for the location of the TLS service protocol is within the Foundation framework. In the short term, the protocol can live within the transport management framework.<br>&gt;&gt; <br>&gt;&gt; <br>&gt;&gt; 7 - References<br>&gt;&gt; <br>&gt;&gt; 1 - </font></tt><a href="https://web.archive.org/web/20150202200348/http://www.objectmentor.com/resources/articles/srp.pdf"><tt><u><font size="2" color="#0000FF">https://web.archive.org/web/20150202200348/http://www.objectmentor.com/resources/articles/srp.pdf</font></u></tt></a><tt><font size="2"><br>&gt;&gt; <br>&gt;&gt; <br>&gt;&gt; <br>&gt;&gt; <br>&gt;&gt; <br>&gt;&gt; <br>&gt;&gt; _______________________________________________<br>&gt;&gt; swift-server-dev mailing list<br>&gt;&gt; swift-server-dev@swift.org<br>&gt;&gt; </font></tt><a href="https://lists.swift.org/mailman/listinfo/swift-server-dev"><tt><u><font size="2" color="#0000FF">https://lists.swift.org/mailman/listinfo/swift-server-dev</font></u></tt></a><tt><font size="2"><br>&gt; <br>&gt; _______________________________________________<br>&gt; swift-server-dev mailing list<br>&gt; swift-server-dev@swift.org<br>&gt; </font></tt><a href="https://lists.swift.org/mailman/listinfo/swift-server-dev"><tt><u><font size="2" color="#0000FF">https://lists.swift.org/mailman/listinfo/swift-server-dev</font></u></tt></a><tt><font size="2"><br><br>_______________________________________________<br>swift-server-dev mailing list<br>swift-server-dev@swift.org</font></tt><tt><u><font size="2" color="#0000FF"><br></font></u></tt><a href="https://lists.swift.org/mailman/listinfo/swift-server-dev"><tt><u><font size="2" color="#0000FF">https://lists.swift.org/mailman/listinfo/swift-server-dev</font></u></tt></a><br><br><br><tt><font size="2">_______________________________________________<br>swift-server-dev mailing list<br>swift-server-dev@swift.org<br></font></tt><tt><font size="2"><a href="https://lists.swift.org/mailman/listinfo/swift-server-dev">https://lists.swift.org/mailman/listinfo/swift-server-dev</a></font></tt><tt><font size="2"><br></font></tt><br><br><BR>
</body></html>