[comment {-*- tcl -*- doctools manpage}]
[manpage_begin "SSL/TLS" n ""]
[copyright "2013 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 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_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]
