[comment {-*- tcl -*- doctools manpage}]
[manpage_begin "SSL/TLS" n ""]
[copyright "2013-2020 Ashok P. Nadkarni"]
[moddesc "Transport Layer Security"]
[titledesc "Secure Sockets Layer and Transport Layer Security Channels"]
[require twapi_crypto]
[description]
[para]

[emph "This module is still experimental and liable to change."]

[para]
This package provides a Tcl channel facility that implements
the Secure Sockets Layer / Transport Layer Security
(collectively referred to as TLS) on top
of the Windows Security Service
Provider Interface (SSPI) interface.

[section "TLS channels"]

The [uri #tls_socket [cmd tls_socket]] command creates a new TCP/IP based
client connection or a listening server socket.

The [uri #starttls [cmd starttls]] command wraps an existing Tcl
bidirectional channel into a TLS channel.

The [uri #tls_handshake [cmd tls_handshake]] command completes
negotiation on a TLS channel. The current channel state can be retrieved
with [uri #tls_state [cmd tls_state]].

Channels are closed using either the [uri #tls_close [cmd tls_close]] command or
the Tcl [cmd close] command. The former permits half-closing of the output side
of the channel which the latter does not allow for reflected channels.

[section "Error handling"]

Errors that occur in the background are reported by [cmd twapi_tls] by
calling the internal command [uri #tls_background_error [cmd tls_background_error]].
This command may be overridden by applications.

[section Commands]

[list_begin definitions]
[call [cmd starttls] [arg CHAN] [opt [cmd -server]] [opt [arg options]]]
Returns a new TLS channel that wraps an existing channel [arg CHAN].
[arg CHAN] must be in an open state.
Caller should use the returned channel and must not access [arg CHAN]
directly after the command returns, [emph "even on errors"].
By default, the returned
channel is for the client end of the connection.
If the option [cmd -server] is specified the channel corresponds
to the server end. This impacts how authentication and certificate
validation is handled.
[nl]
The newly returned channel has the same settings for
[cmd -buffering], [cmd -buffersize], [cmd -encoding], [cmd -eofchar]
and [cmd -translation] as the wrapped channel [arg CHAN]. The
setting for [cmd -blocking] is also preserved.
[emph {
    However, any read or write handlers are not copied to the
    new channel.
}] The caller must recreate them with [cmd {chan configure}].
[nl]
The command supports the following options:
[list_begin opt]
[opt_def [cmd -credentials] [arg CREDENTIALS]]
Specifies the credentials to be used for the connection.
See [uri #tls_socket [cmd tls_socket]] for details.
[opt_def [cmd -peersubject] [arg PEERNAME]]
Specifies the subject name to be verified on the remote certificate.
Must be specified for client side connections and
must not be specified for server-side connections.
[opt_def [cmd -verifier] [arg VERIFYCOMMAND]]
Specifies a callback to invoke to verify remote credentials.
See [uri #tls_socket [cmd tls_socket]] for details.
[list_end]

[call [cmd tls_background_error] [arg MESSAGE] [arg OPTIONDICT]]

This command is internally called by [cmd twapi_tls] to report errors in event
handler during negotiation etc. The default implementation simply raises an
exception which causes the event loop to report the error via the [cmd bgerror]
mechanism. An application may override this if it so chooses, for example to log
or change the message etc.. However, the application defined command must also
raise an exception but has the option of doing so with a different message,
error code and options dictionary. If the application defined command returns
normally, [cmd twapi_tls] will itself raise the original exception.

[nl]
The command is passed the original error message as [arg MESSAGE] and the
error options dictionary as [arg OPTIONDICT].

[call [cmd tls_close] [arg CHAN] [opt [arg DIRECTION]]]
Closes the specified TLS channel. This command is similar to the
standard Tcl [cmd close] command except that the latter does not permit
half-closing of TLS channels as they are implemented using Tcl's
reflected channel framework.

[nl]
If [arg DIRECTION] is not specified, the command behaves identically to
the Tcl [cmd close] command. If [arg DIRECTION] is specified, it must
currently be the value [const write] or any abbreviation of it. The
command will then close the output side of the channel while continuing
to allow data to be read from the channel. Currently half-closing
of the read side is not supported.

[call [cmd tls_handshake] [arg CHAN]]

If [arg CHAN] is a non-blocking TLS channel, the command returns [const 1]
if the TLS negotiation on the channel is completed and [const 0] if it
is still in progress.

If [arg CHAN] is a blocking channel, for example a channel created
with the `-async` option, the command will return only after
completing TLS negotiation. The return value will always be [const 1] in
this case.

The command will raise an error if TLS negotiation fails or the channel
has been closed.

[call [cmd tls_socket] [opt [arg options]] [arg REMOTEADDR] [arg PORT]]
[call [cmd tls_socket] [cmd -server] [arg SERVERCALLBACK] [opt [arg options]] [arg PORT]]
The [cmd tls_socket] command provides the same interface as the Tcl
[cmd socket] command except that the connection runs over TLS or SSL.
[nl]
The first form is used by client-side applications to connect to a remote
server running on port [arg PORT] at address [arg REMOTEADDR]. The latter
form is used by server-side applications to listen for incoming connections
on port [arg PORT].
[nl]
The command options include [cmd -server], [cmd -myaddr], [cmd -myport]
and [cmd -async]. Please refer to the Tcl documentation of the [cmd socket]
command for the use of these options.
[nl]
The [cmd tls_socket] command supports the following additional options:

[list_begin opt]

[opt_def [cmd -credentials] [arg CREDENTIALS]]
Specifies the credentials to be used for the connection.
[arg CREDENTIALS] should be credentials returned from a call to
[uri sspi.html#sspi_acquire_credentials [cmd sspi_acquire_credentials]] using
the [cmd "-package unisp"] option. For client-side connections, this option
only needs to be specified when connecting to servers that require
clients to be authenticated. For server-side connections, this option
is usually required for the connection to complete as most remote clients
will require validation of server certificates.
[opt_def [cmd -peersubject] [arg PEERNAME]]
Specifies the subject name to be verified on the remote certificate.
Only used for client-side connections to verify the name in the
certificate returned by the remote server. If unspecified, defaults
to [arg REMOTEADDR]. This option is silently ignored for server-side
connections.
[opt_def [cmd -requestclientcert]]
Indicates that the client should be asked to send its certificate.
Only applicable to server side sockets and is ignored if
[cmd -server] is not specified.
[emph {
    Note that this option only results in the client being requested
    for its certificate. Unlike server certificates, client certificates
    are not validated by default.
}]
Applications must themselves check that a certificate was received
and validate it, generally by specifying a verification callback
via the [cmd -verifier] option.
[opt_def [cmd -verifier] [arg VERIFYCOMMAND]]
Specifies a callback to invoke to verify remote credentials.
The [arg VERIFYCOMMAND] command prefix is invoked with two additional
parameters - the channel and a handle to the
[uri sspi.html "security context"] for the connection. If the command
returns a [const true] value, the connection is completed. For any other
values or errors, the connection is aborted. The callback can
retrieve the remote certificate from the passed
security context with the
[uri sspi.html#sspi_remote_cert [cmd sspi_remote_cert]] command
and use [uri crypto.html#cert_tls_verify [cmd cert_tls_verify]]
to validate it.
[nl]
For client-side
connections, if this option is specified and is not empty, automatic
verification of the server certificate is not done. For server-side
connections, automatic verification of client certificates is never
done and must be done through this callback.
[list_end]
The channel returned by [cmd tls_socket] may be used with any
of the Tcl channel commands and supports all channel and socket configuration
options. In addition, the following read-only configuration options
are supported:
[list_begin opt]
[opt_def [cmd -credentials]]
Returns the handle to the local credentials for the channel.
[opt_def [cmd -context]]
Returns the handle to the security context for the channel.
[opt_def [cmd -verifier]]
Returns the verification callback for the channel.
[list_end]

[call [cmd tls_state] [arg CHAN]]
Returns the current state of a TLS channel. This may be one of
[const CLIENTINIT], [const SERVERINIT], [const LISTENER],
[const NEGOTIATING], [const OPEN] or [const CLOSED].

[list_end]

[keywords SSL TLS encryption decryption SSPI schannel]

[manpage_end]
