All Manuals > LispWorks User Guide and Reference Manual > 25 TCP and UDP socket communication and SSL

NextPrevUpTopContentsIndex

25.7 Socket Stream SSL interface

The Socket Stream SSL interface allows you to use Secure Socket Layer (SSL) with Lisp objects of type socket-stream.

The interface is based on the OpenSSL code, and most of it is simply an FLI interface to OpenSSL functions. The main LispWorks specific code is the way OpenSSL is integrated with socket-stream.

The Socket Stream SSL interface is in the "comm" module, so to load it you evaluate

(require "comm")

Note: In this section we assume that the current package uses the comm package. That is, comm package symbols may not be qualified explicitly.

25.7.1 Creating a stream with SSL

There are three ways to make a socket-stream with SSL processing:

For example:

(open-tcp-stream some-url 443 :ssl-ctx t)

25.7.2 SSL-CTX and SSL objects

When the value of the :ssl-ctx argument is a symbol, LispWorks automatically creates an SSL_CTX object and an SSL object and uses them. If you need to configure these objects, you can access them by the following methods:

25.7.3 OpenSSL interface

The configuration interface contains mostly FLI function definitions that map directly to OpenSSL calls. See below for a list of those provided.

There are also some functions to make common cases simpler. These are read-dhparams, pem-read, set-ssl-ctx-options, set-ssl-ctx-password-callback, and set-ssl-ctx-dh.

25.7.3.1 OpenSSL constants

The Lisp constants SSL_FILETYPE_ASN1 and SSL_FILETYPE_PEM representing file types are provided.

25.7.3.2 Naming conventions for direct OpenSSL calls

This section describes the mapping between OpenSSL function names and the corresponding Lisp names.

25.7.3.3 Mapping C names to Lisp names

For functions that map directly to OpenSSL calls, the convention is to create the LISP name from the C name by replacing underscores by hyphens.

25.7.3.4 Mapping Lisp names to C names

To find the C name from the LISP function name:

  1. the hyphens need to be replaced by underscores, and
  2. the initial SSL or SSL_CTX has to be in uppercase, and
  3. the rest has to be lowercase, except that
  4. the following phrases are cased specially, like this: "RSAPrivateKey", "DSH ", "ASN1", "CA", "PrivateKey"

25.7.4 Direct calls to OpenSSL

The following functions map directly to the OpenSSL functions. Check the OpenSSL documentation for details.

Where an OpenSSL function takes an SSL* or SSL_CTX*, the Lisp function's argument must be a foreign pointer of type ssl-pointer, ssl-ctx-pointer or ssl-cipher-pointer. Where an OpenSSL function takes a char* or int, the Lisp function's argument must be a string or integer. Where an OpenSSL function takes other kinds of pointers, the Lisp function's argument must be a foreign pointer. The return values are integers or foreign pointers unless stated otherwise.

If an error occurs in one of these functions, an error code is returned. They do not signal any Common Lisp conditions and so you should check the return value carefully.

 

Direct calls to OpenSSL

Lisp function

Return values

ssl-add-client-ca

 

ssl-cipher-get-bits

First value is number of bits the cipher actually uses.
Second value is number of bits the algorithm of the cipher can use (which may be higher).

ssl-cipher-get-name

string.
e.g. "DHE-RSA-AES256-SHA"

ssl-cipher-get-version

string.
e.g. "TLSv1/SSLv3"

ssl-clear-num-renegotiations

 

ssl-ctrl

 

ssl-ctx-add-client-ca

 

ssl-ctx-add-extra-chain-cert

 

ssl-ctx-ctrl

 

ssl-ctx-get-max-cert-list

 

ssl-ctx-get-mode

 

ssl-ctx-get-options

 

ssl-ctx-get-read-ahead

 

ssl-ctx-get-verify-mode

integer

ssl-ctx-load-verify-locations

 

ssl-ctx-need-tmp-rsa

 

ssl-ctx-sess-set-cache-size

 

ssl-ctx-sess-get-cache-size

 

ssl-ctx-sess-set-cache-mode

 

ssl-ctx-sess-get-cache-mode

 

ssl-ctx-set-client-ca-list

 

ssl-ctx-set-max-cert-list

 

ssl-ctx-set-mode

 

ssl-ctx-set-options

 

ssl-ctx-set-read-ahead

 

ssl-ctx-set-tmp-rsa

 

ssl-ctx-set-tmp-dh

 

ssl-ctx-use-certificate-chain-file

 

ssl-ctx-use-certificate-file

 

ssl-ctx-use-privatekey-file

 

ssl-ctx-use-rsaprivatekey-file

 

ssl-get-current-cipher

ssl-cipher-pointer
Can be a null pointer.

ssl-get-max-cert-list

 

ssl-get-mode

 

ssl-get-options

 

ssl-get-verify-mode

integer

ssl-get-version

string
"TLSv1", "SSLv2" or "SSLv3"

ssl-load-client-ca-file

 

ssl-need-tmp-rsa

 

ssl-num-renegotiations

 

ssl-session-reused

 

ssl-set-accept-state

None

ssl-set-client-ca-list

 

ssl-set-connect-state

None

ssl-set-max-cert-list

 

ssl-set-mode

 

ssl-set-options

 

ssl-set-tmp-rsa

 

ssl-set-tmp-dh

 

ssl-total-renegotiations

 

ssl-use-certificate-file

 

ssl-use-rsaprivatekey-file

 

ssl-use-privatekey-file

 

If you need OpenSSL functionality that is not provided here, you can define your own foreign functions via the LispWorks Foreign Language Interface.

If you do this, an important point to note is that on Microsoft Windows, the :calling-convention must be :cdecl (it defaults to :stdcall). If using OpenSSL suddenly causes mysterious crashes, the calling-convention in your foreign function definitions is the first thing to check.

25.7.5 Socket Stream SSL keyword arguments

The keyword arguments :ssl-ctx, :ssl-side, :ctx-configure-callback and :ssl-configure-callback can be be passed to create and configure socket streams with SSL processing. The various methods for creating and configuring SSL streams accept these keyword arguments as shown in SSL configuration keywords.

 

SSL configuration keywords

 

:ssl-ctx

:ssl-side

:ctx-configure-callback

:ssl-configure-callback

socket-stream make-instance

Yes

Yes

Yes

Yes

open-tcp-stream

Yes

No

Yes

Yes

attach-ssl

Yes

Yes

Yes

Yes

make-ssl-ctx

Yes

Yes

No

No

(make-instance 'socket-stream ...) and open-tcp-stream, when ssl-ctx is non-nil, call attach-ssl and pass it all the arguments.

:ssl-ctx specifies that SSL should be used, and also specifies the SSL_CTX object to use. See the OpenSSL manual entry for SSL_CTX_new for details of making a SSL_CTX. The value of ssl-ctx can be:

A symbol

Together with ssl-side, this symbol specifies which protocol to use. ssl-ctx can be one of:

1) t or :default, meaning use the default. Currently this is the same as :v23.

2) One of :v2, :v3, :v23 or :tls-v1. These are mapped to the SSLv2_*, SSLv3_*, SSLv23_*, TLSv1_* methods.

LispWorks makes a new SSL_CTX object and uses it and frees it when the stream is closed. make-instance, attach-ssl and open-tcp-stream also make an SSL object, use it and free it when the stream is closed.

A foreign pointer of type ssl-ctx-pointer

This corresponds to the C type SSL_CTX*. This is used and is not freed when the stream is closed. make-instance, attach-ssl and open-tcp-stream also make an SSL object, use it and free it when the stream is closed. The foreign pointer maybe a result of a call to make-ssl-ctx, but it can also be a result of your code, provided that it points to a valid SSL_CTX and has the type ssl-ctx-pointer .

A foreign pointer of type ssl-pointer

This corresponds to the C type SSL*. This specifies the SSL to use in make-instance, attach-ssl and open-tcp-stream. This maybe a result of a call to ssl-new. but can also be a result of your code, provided that it points to a valid SSL object and has the type ssl-pointer . The SSL is used and is not freed when the stream is closed.

When you pass a ssl-ctx-pointer or a ssl-pointer foreign pointer, these must have already been set up correctly.

:ssl-side specifies which side the stream is. The value ssl-side can be one of :client, :server or :both. open-tcp-stream does not take this keyword and always uses :client. For the other calls this argument defaults to :server. The value of ssl-side is used in two cases:

When a new SSL_CTX object is created, it is used to select the method:

:client => *_client_method

:server => *_server_method

:both => *_method

When a new SSL object is created, when ssl-side is either :client or :server, LispWorks calls ssl-set-connect-state or ssl-set-accept-state respectively.

If the value of ssl-ctx is a ssl-pointer , ssl-side is ignored.

:ctx-configure-callback specifies a callback, a function which takes a foreign pointer of type ssl-ctx-pointer . This is called immediately after a new SSL_CTX is created. If the value of ssl-ctx is not a symbol, ctx-configure-callback is ignored.

:ssl-configure-callback specifies a callback, a function which takes a foreign pointer of type ssl-pointer . This is called immediately after a new SSL is created. If the value of ssl-ctx is not a ssl-pointer, ssl-configure-callback is ignored.

25.7.6 Attaching SSL to an existing socket-stream

You can attach SSL to an existing socket-stream by calling attach-ssl on the stream. attach-ssl ensures the OpenSSL library is loaded and seeds the Pseudo Random Number Generator (PRNG). The socket-stream SSL keyword arguments are processed by attach-ssl as described in Socket Stream SSL keyword arguments.

Detach SSL from a socket-stream and shut down the SSL with detach-ssl.

For full descriptions see attach-ssl and detach-ssl.

25.7.7 Using SSL objects directly

The C objects SSL and SSL_CTX are represented in LispWorks by foreign pointers with type ssl-pointer and ssl-ctx-pointer, which correspond to the C types SSL* and SSL_CTX*. These foreign types should be used for any foreign function that takes or returns these C types, and must be used when passing a foreign pointer as the value of the :ssl-ctx argument.

Making SSL objects is a way of getting access to them to perform configuration, but, especially in the case of the SSL_CTX, it is a useful way to avoid repeated calls to the configuration routines which may be time consuming. For example, if we have defined a function configure-a-ctx, and we want to read once every 60 seconds from some URL, we can write:

(loop (with-open-stream
          (str (comm:open-tcp-stream some-url
 443 :ssl-ctx t
                                     :ctx-configure-callback 'configure-a-ctx))
        (read-something str))
      (sleep 60))

This will cause configure-a-ctx to be called each time. If it is expensive, we can call it only once by changing the code to:

(let ((ctx (comm:make-ssl-ctx :ssl-side :client)))
  (configure-a-ctx ctx)
  (loop (with-open-stream
    (str (comm:open-tcp-stream some-url
 443 :ssl-ctx ctx))
          (read-something str))
        (sleep 60))
  (ssl-ctx-free ctx))

The SSL objects could be made either by make-ssl-ctx or ssl-new or by user code that calls the C functions SSL_CTX_new and SSL_new. destroy-ssl-ctx frees the SSL_CTX object. To free an SSL object you would call destroy-ssl. See the manual entries for full descriptions of these functions.

25.7.8 Initialization

All the functions that make a SSL_CTX first call ensure-ssl, so normally you do not need to initialize the library. If your code makes a SSL_CTX itself (that is, not by calling any of the LispWorks interface functions), it needs to initialize the library first. Normally that should be done by an explicit call to ensure-ssl, which loads the SSL library and calls SSL_library_init and SSL_load_error_strings, and also does some LispWorks specific initializations. If your code must do the initialization, ensure-ssl should still be called with the argument :already-done t, which tells it that the library is already loaded and initialized.

25.7.9 Obtaining and installing the OpenSSL library

At the time of writing, OpenSSL is available as shown in OpenSSL availability:

OpenSSL availability

Operating System

Availability of OpenSSL

Linux

Installed by default on most 32-bit and 64-bit distributions

Windows

32-bit and 64-bit libraries are available at
www.slproweb.com/products/Win32OpenSSL.html

Mac OS X

32-bit and 64-bit libraries are installed by default.

FreeBSD

Installed by default

AIX

Installed by default

x86/x64 Solaris

Installed by default

SPARC Solaris

Installed by default on Solaris 10. For other versions, see the freeware from Sun at
sunfreeware.com for both 32-bit and 64-bit.

25.7.9.1 Installing the OpenSSL library on Solaris

After installing (with pkgadd) you need to put the shared libraries libcrypto.so and libssl.o on the loader path. By default these are installed in /usr/local/ssl/lib.

To add the libraries to the loader path, either

25.7.9.2 Loading the OpenSSL libraries

Since OpenSSL is not a standard on all machines yet, the location of the library or libraries varies. By default, ensure-ssl loads libraries as shown in Loading the OpenSSL libraries.

 

Loading the OpenSSL libraries

Operating System

Libraries

Linux

-lssl

Windows

libeay32.dll libssl32.dll

Solaris

-lssl

AIX

-lssl

Mac OS X

-lssl

Others

nil

On machines where the path is unknown or is incorrect, you must set the path. Do this by calling set-ssl-library-path , or by passing the path as the library-path argument to ensure-ssl.

25.7.10 Errors in SSL

If there are errors inside SSL, LispWorks will signal an error of type ssl-condition , which is a subclass of socket-error .

The condition can be one of the types ssl-x509-lookup , ssl-closed , ssl-error and ssl-failure . See the manual pages for details of these condition classes.

25.7.11 Examples of using the socket stream SSL interface

See the example files in:

(example-edit-file "ssl/")

LispWorks User Guide and Reference Manual - 13 Feb 2015

NextPrevUpTopContentsIndex