Pike SSL/TLS Implementation Notes
=================================

SSL/TLS Standard Documents and Amount of Coverage
-------------------------------------------------

  SSL and TLS are specified in quite a few documents;
  the following is an attempt to list them all, and
  the level of implementation in Pike.

Legend:

 [ ] Not implemented at present.

 [-] Not implemented and will not be implemented.
     Typically an obsolete or insecure standard.

 [/] Partially implemented.

 [X] Fully implemented.

 NB: Constants from documents marked as not implemented may
     still be added to SSL.Constants for debug purposes.

The SSL 2.0 protocol was specified in the following document:

 [-] SSL 2.0				draft-hickman-netscape-ssl-00.txt

The SSL 3.0 Protocol was specified in the following draft (later an RFC):

 [X] SSL 3.0				draft-freier-ssl-version3-02.txt
 [X] SSL 3.0				RFC 6101

The TLS 1.0 Protocol is specified in the following RFCs:

 [X] SSL 3.1/TLS 1.0			RFC 2246
 [/] Kerberos for TLS 1.0		RFC 2712
 [X] AES Ciphers for TLS 1.0		RFC 3268
 [/] Extensions for TLS 1.0		RFC 3546
 [X] TLS Compression Methods		RFC 3749
 [ ] LZS Compression for TLS		RFC 3943
 [X] Camellia Cipher for TLS		RFC 4132
 [ ] SEED Cipher for TLS 1.0		RFC 4162
 [X] Pre-Shared Keys for TLS		RFC 4279

The TLS 1.1 Protocol is specified in the following RFCs:

 [X] SSL 3.2/TLS 1.1			RFC 4346
 [/] Extensions for TLS 1.1		RFC 4366
 [X] ECC Ciphers for TLS 1.1		RFC 4492
 [X] Session Resumption			RFC 4507
 [ ] TLS Handshake Message		RFC 4680
 [ ] User Mapping Extension		RFC 4681
 [X] PSK with NULL for TLS 1.1		RFC 4785
 [ ] SRP with TLS 1.1			RFC 5054
 [X] Session Resumption			RFC 5077
 [ ] OpenPGP Authentication		RFC 5081
 [X] Authenticated Encryption		RFC 5116

The DTLS 1.0 Protocol is specified in the following RFCs:

 [ ] DTLS 1.0				RFC 4347
 [ ] DTLS over DCCP			RFC 5238

The TLS 1.2 Protocol is specified in the following RFCs:

 [X] SSL 3.3/TLS 1.2			RFC 5246
 [X] AES GCM Cipher for TLS		RFC 5288
 [X] ECC with SHA256/384 & GCM		RFC 5289
 [/] Suite B Profile for TLS		RFC 5430
 [X] DES and IDEA for TLS		RFC 5469
 [X] Pre-Shared Keys with GCM		RFC 5487
 [X] ECDHE_PSK Cipher for TLS		RFC 5489
 [X] Renegotiation Extension		RFC 5746
 [ ] Authorization Extensions		RFC 5878
 [X] Camellia Cipher for TLS		RFC 5932
 [ ] KeyNote Auth for TLS		RFC 6042
 [/] TLS Extension Definitions		RFC 6066
 [ ] OpenPGP Authentication		RFC 6091
 [ ] ARIA Cipher for TLS		RFC 6209
 [ ] Additional Master Secrets		RFC 6358
 [X] Camellia Cipher for TLS		RFC 6367
 [/] Suite B Profile for TLS		RFC 6460
 [X] Heartbeat Extension		RFC 6520
 [X] AES-CCM Cipher for TLS		RFC 6655
 [ ] Multiple Certificates		RFC 6961
 [ ] Certificate Transparency		RFC 6962
 [ ] ECC Brainpool Curves		RFC 7027
 [ ] Raw Public Keys in (D)TLS		RFC 7250
 [X] AES-CCM ECC Suites for TLS		RFC 7251
 [X] TLS ALPN Extension			RFC 7301
 [X] TLS Encrypt-then-MAC		RFC 7366
 [ ] Known Attacks on TLS and DTLS	RFC 7457
 [X] Prohibit RC4			RFC 7465
 [X] TLS Fallback SCSV			RFC 7507
 [ ] Recommendations for TLS and DTLS	RFC 7525
 [/] Session Hash and Extended MS	RFC 7627
 [X] TLS Padding			RFC 7685
 [ ] Curve25519/Curve448                RFC 7748
 [ ] Chacha20Poly1305 Suites for TLS	RFC 7905
 [ ] TLS False Start			RFC 7918
 [X] Negotiated FF-DHE Parameters	RFC 7919
 [ ] ECC Cipher Suites for TLS 1.2	RFC 8422
 [ ] ECDHE_PSK with AES-GCM & AES-CCM	RFC 8442

The DTLS 1.2 Protocol is specified in the following RFCs:

 [ ] DTLS 1.2				RFC 6347

The TLS 1.3 Protocol is specified in the following RFCs:

 [ ] SSL 3.4/TLS 1.3			RFC 8446
 [ ] Handshake Traces for TLS 1.3	RFC 8448
 [ ] Using Early Data in HTTP		RFC 8470

General:

 [ ] Registry Updates for TLS & DTLS	RFC 8447
 [ ] Record Size Limit Extension	RFC 8449
 [ ] Token Binding Protocol Version 1.0	RFC 8471
 [ ] Token Binding Protocol Extension	RFC 8472
 [ ] Token Binding over HTTP		RFC 8473

Drafts (in order of age, oldest first):
 [/] 56-bit Export Cipher		draft-ietf-tls-56-bit-ciphersuites-01.txt
 [-] Next Protocol Negotiation  	draft-agl-tls-nextprotoneg

The TLS parameters registry:
  http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml


SSL.File and Stdio.File Emulation Overview
------------------------------------------

Stream:
	The underlying stream object is always in nonblocking
	mode, to avoid risk of hanging in Stdio.Buffer.

Buffering:
	All I/O-ops are always buffered with Stdio.Buffer.

Internal Callback Handling in Nonblocking Mode:
	In nonblocking mode all internal callback handling is
	performed directly with the real_backend.

	If the main backend has been started (ie master()->asyncp()
	is true), we assume that it will handle I/O.
	Otherwise if nonthreaded or we are on the backend thread
	(master()->backend_thread()), we rotate the real_backend
	once with 0.0 timeout per I/O-op.

	Note that this may cause problems when using custom
	backends without having started the main backend.
	Detect?

Internal Callback Handling in Blocking Mode:
	In blocking mode all internal callback handling is
	performed with a dedicated local_backend.

	The local_backend is created when the SSL.File is
	switched to blocking mode.

	The local_backend is then rotated until the blocking
	call is done.

User Callback Handling:
	All user installed callbacks are called via call_out()
	on internal_poll() in the real_backend.

read():
	Get data from user_read_buffer, install ssl_read_callback
	on underflow. In blocking mode rotate the local backend
	until all data is available. In nonblocking mode
	attempt to rotate the local backend once if no callbacks
	are installed.

write():
	Fill write_buffer, install ssl_write_callback.
	In blocking mode rotate the local backend until
	the write_buffer is empty. In nonblocking mode
	attempt to rotate the local backend once if
	no callbacks are installed.

close():
	Schedule a close packet, and block further calls to
	write. If both directions block also further calls
	to read. Install both ssl_write_callback and
	ssl_read_callback and rotate the local backend until
	connection closed from other end, or linger time expires.

_destruct()
	Clear user callbacks and switch to nonblocking mode.
	Attempt to send a close packet. Terminate the
	internal_poll() call_out-loop.

ssl_read_callback():
	Decode received data and add it to user_read_buffer.
	Schedule read_callback with real_backend call_out.
	Uninstall on user_read_buffer full.

ssl_write_callback():
	Send data from write_buffer, uninstall on write_buffer empty.
	Schedule write_callback with real_backend call_out.
	On send failure, block futher calls of write.

ssl_close_callback():
	Schedule close_callback if close() has not been called yet.
	Block further calls of read.

ssl_close_alert_callback():
	As ssl_close_callback, but allow use of stream when done.


Known Problems and Missing Features
-----------------------------------

	Nonblocking mode without callbacks.

	Support for set_buffer_mode() et al not yet supported,
	neither directly nor in the embedded stream.

	Session objects should be possible to serialize with
	encode_value() to allow multiple frontend nodes to share the
	session cache. (Overloading the session cache functionality in
	Context is already easy to do)

	The handshake message hash should be streaming and discard raw
	data after each packet. Also, it is probably possible to find
	only one place in the code where data can be fed to the
	streaming hash.

	Currently Pike will always try to maximize the number of bits
	used for certificates, key exchanges, cipher keys and
	hashes. Another popular approach that should be supported is
	to minimize the bits used, above the set threshold. The
	rationale is that everything allowed is good enough and the
	capability negotiation should optimize on consumed resources.

	Servers with different certificates and parameters can sit on
	the same port with different SNI, or with different ALPN. We
	should make it possible to select Context based on negotiation
	(made tricky, as the negotiation depends on the Context).

	It should be possible to lazy load certificates to increase
	startup time and reduce memory usage for servers with many
	sites. Dynamic loading and unloaded could be part of the same
	mechanism as the Context selection mentioned above.

	Truncated HMAC is only supported on the server side. It has
	however been mentioned on the IETF TLS mailing list that there
	are security issues with truncated HMAC, so this is only
	lacking for completeness.

	Ticket-based session resumption is supported on both client-
	and server-side. To avoid security pitfalls, the server-side
	is however by default not state-less. Making it state-less
	can be done by overriding SSL.Context::encode_session() and
	SSL.Context::decode_session() with a suitable encoding.

Notes about DTLS
----------------

Example raw initial DTLS 1.0 handshake packet from openssl s_client:

Packet #0: (DTLS Plaintext)
  16				Content type #22 (handshake)
  fe ff				Protocol version DTLS 1.0
  00 00				Epoch 0
  00 00 00 00 00 00		Sequence number #0
  00 7e				Packet length
  Fragment: (Handshake)
     01				Message type #1 (ClientHello)
     00 00 72			Handshake packet length
     00 00			Handshake sequence number #0
     00 00 00			Handshake fragment offset
     00 00 72			Handshake fragment length
     fe ff			Protocol version DTLS 1.0
     15 a9 20 74 0e 38 09 50
     40 04 9a 39 fe 8a 93 35
     29 a7 74 12 83 24 94 d0
     d1 54 c3 1f 19 01 05 dd	Random
     00				SessionID
     00				DTLS cookie
     Cipher suites:
        00 12			length
	c0 0a
	c0 14
	00 39
	c0 09
	c0 13
	00 33
	00 35
	00 2f
	00 ff
     Compression methods:
	01			length
	00			None
     Extensions:
	00 36				length
	Extension:
	   00 00			Server name
	   00 0e			length
	      00 0c			length
	      00 00
	      09 6c 6f 63 61 6c 68 6f 73 74	"localhost"
	Extension:
	   00 0b			EC Point Formats
	   00 04			length
	      03			length
	      00 01 02
	Extension:
	   00 0a			Elliptic curves
	   00 0c			length
	      00 0a			length
	      00 1d			x25519
	      00 17			secp256r1
	      00 1e			x448
	      00 19			secp521r1
	      00 18			secp384r1
	Extension:
	   00 23			Session ticket
	   00 00			""
	Extension:
	   00 16			Encrypt then mac
	   00 00			""
	Extension:
	   00 17			Extended master secret
	   00 00			""

Resent Packet #1: (DTLSPlaintext)

  16					Content type #22
  fe ff					DTLS 1.0
  00 00					Epoch 0
  00 00 00 00 00 01			Sequence number #1
  00 7e					Packet length
  [... Remainder identical to packet #0 ...]

[...]

Resent packet #12: (DTLSPlaintext)

  16					Content type #22
  fe ff					DTLS 1.0
  00 00					Epoch 0
  00 00 00 00 00 0c			Sequence number #12
  00 7e					Packet length
  [... Remainder identical to packet #0 ...]

Terminates after packet #12 and ~493 seconds.

Likely exponential backoff timeout for resend.
