TLS (SSL) Tcl Commands
Author: Matt Newman <matt@novadigm.com>

  NAME
    tls - binding to OpenSSL toolkit.
  SYNOPSIS
    package require tls ?1.3?
    tls::init ?options?
    tls::socket ?options? host port
    tls::socket ?-server command? ?options? port
    tls::handshake channel
    tls::status channel
    tls::import channel ?options?
    tls::ciphers protocol ?verbose?
  COMMANDS
  CONFIGURATION OPTIONS
  HTTPS EXAMPLE
  SPECIAL CONSIDERATIONS
  SEE ALSO

### NAME

tls - binding to OpenSSL toolkit.

### SYNOPSIS

package require tls ?1.3?
tls::init ?options?
tls::socket ?options? host port
tls::socket ?-server command? ?options? port
tls::status channel
tls::handshake channel
tls::import channel ?options?
tls::ciphers protocol ?verbose?

### DESCRIPTION

This extension provides a generic binding to OpenSSL, utilizing the Trf Channel Stacking patch for Tcl 8.[01] and the new Tcl_StackChannel API for Tcl 8.2 and higher. The sockets behave exactly the same as channels created using Tcl's built-in socket command with additional options for controlling the SSL session.

### COMMANDS

Typically one would use the tls::socket command which provides compatibility with the native Tcl socket command. In such cases tls::import should not be used directly.

tls::init ?options?
  This routine sets the default options used by tls::socket and is optional. If you call tls::import directly this routine has no effect. Any of the options that tls::socket accepts can be set using this command, though you should limit your options to only TLS related ones.
tls::socket ?options? host port
tls::socket ?-server command? ?options? port
  This is a helper function that utilizes the underlying commands (tls::import). It behaves exactly the same as the native Tcl socket command except that the options can include any of the applicable tls:import options.
tls::handshake channel
  Forces handshake to take place, and returns 0 if handshake is still in progress (non-blocking), or 1 if the handshake was successful. If the handshake failed this routine will throw an error.
tls::status channel
  Returns the current security status of a SSL channel. The result is a list of key value pairs describing the connected peer. If the result is an empty list then the SSL handshake has not yet completed.

> issuer dn
>   The distinguished name (DN) of the certificate issuer.
> subject dn
>   The distinguished name (DN) of the certificate subject.
> notBefore date
>   The begin date for the validity of the certificate.
> notAfter date
>   The expiry date for the certificate.
> serial n
>   The serial number of the certificate.
> cipher cipher
>   The current cipher in use between the client and server channels.

tls::import channel ?options?
  SSL-enable a regular Tcl channel - it need not be a socket, but must provide bi-directional flow. Also setting session parameters for SSL handshake.

> -cafile filename
>   Provide the CA file.
> -cadir dir
>   Provide the directory containing the CA certificates.
> -certfile filename
>   Provide the certificate to use.
> -cipher string
>   Provide the cipher suites to use. Syntax is as per OpenSSL.
> -command callback
>   This callback is invoked to pass errors, tracing information and to allow Tcl scripts to perform additional verification of the certificate, which can override the default validation in OpenSSL.
> -keyfile filename
>   Provide the private key file. (default: value of -certfile)
> -model channel
>   This will force this channel to share the same SSL_CTX structure as the specified channel, and therefore share callbacks etc.
> -request bool
>   Request a certificate from peer during SSL handshake. (default: true)
> -require bool
>   Require a valid certificate from peer during SSL handshake. If this is set to true then -request must also be set to true. (default: false)
> -server bool
>   Handshake as server if true, else handshake as client.(default: false) [Not available to tls::socket]
> -ssl2 bool
>   Enable use of SSL v2. (default: true unless -DNO_PATENTS was specified in build)
> -ssl3 bool
>   Enable use of SSL v3. (default: true)
> -tls1 bool
>   Enable use of TLS v1. (default: false)

tls::ciphers protocol ?verbose?
  Returns list of supported ciphers based on the protocol you supply, which must be one of ssl2, ssl3, or tls1. If verbose is specified as true then a verbose, semi-human readable list is returned providing additional information on the nature of the cipher support. In each case the result is a Tcl list.

### CONFIGURATION OPTIONS

In addition to the options listed above you can set the tls::debug flag to a non-zero value to see the output from the default command callback (tls::callback) which shows the progression of the SSL handshake. Setting this value to greated than 1 will cause the default verify method in tls::callback to always accept the certificate, even if it is invalid.

In a real-world deployment you should substitute your own callback in place of tls::callback, via the -command option to tls::socket or tls::import.

When the TLS layer needs to obtain a password, typically for a certificate, the software will invoke a Tcl command called tls::password, which should return a string which represents the password to be used. A default implementation is provided, which simply returns "secret" - you should redefine this procedure after issuing the package require tls.

### HTTPS EXAMPLE

This example requires a patch to the http module that ships with Tcl - this patch has been submitted for inclusion in Tcl 8.2.1, but is also provided in the tls directory if needed. A sample server.pem is provided with the TLS release, courtesy of the OpenSSL project.

    package require http
    package require tls

    http::register https 443 [list ::tls::socket -require 1 -cafile ./server.pem]

    set tok [http::geturl https://developer.netscape.com/]

### SPECIAL CONSIDERATIONS

The capabilities of this package can vary enormously based upon how your OpenSSL library was configured and built. At the most macro-level OpenSSL supports a "no patents" build, which disables RSA, IDEA, RC(2,4,5) and SSL2 - if your OpenSSL is configured this way then you will need to build TLS with the -DNO_PATENTS option - and the resultant module will function correctly and also support ADH certificate-less encryption, however you will be unable to utilize this to speak to normal Web Servers, which typically require RSA support. Please see http://www.openssl.org/ for more information on the whole issue of patents and US export restrictions.

### SEE ALSO

socket, fileevent, OpenSSL

    Copyright © 1999 Matt Newman.