-
Status: draft
-
Authors: Garrett D’Amore
-
Version 1.3.1
Copyright 2017 Garrett D’Amore
Copyright 2017 Capitar IT Group BV
Copyright 2017 Staysail Systems
This specification is licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the license online.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.
This mapping should be layered directly on the top of TLS v1.2 secured connections. While it is possible to use TLS on top of other transports, this document specifically concerns itself with TLS running on top of TCP.
Other combinations may be contemplated, and should follow the same details as discussed here.
As when running SP over TCP directly, the TCP port number is determined by the application or user.
Implementations MUST NOT support versions of TLS or SSL older than v1.2. Implementations MAY support newer versions, and SHOULD avoid using algorithms or features removed from newer versions.
Note
|
It is our intent that when TLS v1.3 is finalized, to support, and possibly even mandate, the use of TLS v1.3. |
Implementations MUST NOT use RC4, DES, MD5, SHA1, or any algorithm in CBC (cipher-block-chaining) mode. This prohibition applies to both use in cipher suites and in certificates.
Implementations MUST NOT use RSA, DSA, or DH public key algorithms with key lengths smaller than 1024 bits, and SHOULD use 2048-bit key lengths or larger.
Implementations MUST NOT use renegotiation. An attempt to renegotiate MUST cause the connection to be closed immediately.
Implementations MUST NOT use session resumption, but MUST instead open a new TCP port when creating a new session, and MUST close the underlying TCP when completing a session (after processing any CLOSE-NOTIFY messages. (It is assumed that implementations will generally use long-lived connections, and elimination of session resumption leads to simpler, and therefore more secure, implementation.)
Implementations MUST NOT use TLS layer compression, as it has been found to weak TLS. (Compression MAY be done by the application in the layer above, if it is needed.)
Certificate and key management are out of scope for this document.
The first phase of connections involves setting up the TLS connection. The details of this are not specific to this protocol. Implementations MUST validate remote peers using standard TLS verification methods. The specific validation checks, such as certificate enforcement and time/date checks SHOULD be administrator configurable.
If a secure TLS connection cannot be established, then the underlying connection MUST be closed immediately. (Each peer may apply it’s own checks in determining whether the connection is secure or not.)
As soon as the TLS connection is established, both peers MUST send a protocol header immediately. The protocol header has the following form, in big-endian:
{ colwidth = 32 0-7: 0x00 8-15: 0x53 16-23: 0x50 24-31: version 32-47: type 48-63: reserved }
The version
field MUST be zero.
The first three bytes are used to identify that the connection is being used for scalability protocols (note that in ASCII this will look like "\0SP"), using this version of the standard (0x0).
The 16-bit type
field corresponds to the numeric scalability
protocol ID of the sender. For example, a PAIRv1 sender would use the
numeric value 0x11 here, corresponding to the PAIR protocol version 1.
The final 16-bit reserved
field MUST be set to zero.
After each peer sends this initial handshake message, they MUST wait until the other peers handshake message is received.
Each peer MUST validate that the remote peer is using the same
values for the first 32-bits, and that the type
fields are compatible.
Additionally the reserved
field MUST be zero.
If any of these validation checks, the peer MUST close the connection. No error indication is sent to the other peer.
Each SP message sent over this mapping is prefixed by a 64-bit[1] (big-endian) length, followed by the payload:
{ colwidth = 32 0-63: payload size 64-95: payload ... [colheight = 3] }
The payload size
represents the size of the payload
field, in octets.
The payload
field may be absent, in which case the payload size
field
will be zero. (This would indicate an empty message.)
Sending the size in advance allows the receiver to preallocate a buffer large enough to hold the entire incoming message. It also offers the receiver a chance to reject messages larger than it is willing to accept, which can be useful for avoiding certain forms of denial-of-service attacks.
Implementations MUST support a configurable maximum limit on the received message size. It is RECOMMENDED the default value for this be one megabyte. Implementations MUST also support disabling this check.
If an implementation choosed to reject a received message as too large, it MUST immediately close the connection.
While some modern protocols multiplex multiple communications channels over a single TCP or TLS stream, we have chosen not to do this. Typically this is done to mitigate against the high cost of the 3-way TCP handshake used when setting up a connection. Such approaches benefit primarily applications with very short-lived TCP connections.
In contrast, we expect most SP applications to use longer lived connections.
Don’t cross the streams.
Ghostbusters
Protocols which multiplex multiple channels are subject to head-of-line blocking, where one slow channel can have a detrimental impact on others. Additionally, they add a great deal more complexity, and usually require extra data copying.
The URI scheme used to represent TLS addresses is similar that used for TCP.
The format SHALL be tls+tcp://host:port
, where the host
represents either an Internet host name, or an IP address, and the port
represents the TCP port number used.
When specifying an IPv6 address for the host, the address SHALL be
enclosed in square backets ([
and ]
) to avoid confusion with the final colon
separating the IP address and the port. For example, to specify the IPv6
loopback address, and port 4300, the URI would be tls+tcp://[::1]:4300
.
A responder MAY elide the host portion, to just bind to itself,
in which case the format will be tls+tcp://:port
.
Implementations MAY offer the ability to specify a wild card of *
when listening to indicate that the server should listen on all locally
configured IP addresses.
Implementations MAY allow a port number of 0 to be specified when listening, in which case a randomly chosen ephemeral TCP port SHALL be used.[2]
The correct configuration and administration of TLS is required to provide a channel secure from eavesdropping, modification, and replay attacks. The discussion of how to do this, and the important details around key and certificate administration, are implementation specific and out of scope for this document.
Denial-of-service considerations are discussed, in particular the use of a limit on the incoming message sizes.