The SSL interface is part of the
"comm" module, so to load it you evaluate:
Note: In this section we assume that the current package uses the
comm package. That is,
comm package symbols may not be qualified explicitly.
The LispWorks SSL interface is implemented using an underlying SSL implementation, which may be either OpenSSL or the Apple Security Framework (sometimes shortened to just "Apple"). The Apple Security Framework implementation is new in LispWorks 8.0, and is available only on macOS 10.8 or later or iOS. It is the default implementation on these platforms. All other platforms and previous versions of LispWorks support only the OpenSSL implementation, so if you are not going to use SSL on Apple products all you need to know is to ignore any Apple specific features.
Implementation are named
:openssl for OpenSSL and
:apple for the Apple Security Framework.
In general, you will usually use only one of the implementations on a particular operating system, even on the operating systems that support both, but it is possible to use both of them at the same time (for different SSL connections). At any time, one of the implementations is the default implementation, and any SSL connections that are created without specifying the implementation explicitly will use this default implementation. To query and set the default implementation, you can use the accessor ssl-default-implementation. To check if an implementation is available, you can call the function ssl-implementation-available-p.
To make it easier to write code that can work with both implementations, as well as adding new features and simplifying using SSL, in LispWorks 8.0 and newer you can configure SSL connections using an abstract context. See 25.8.3 SSL abstract contexts for details.
For details of the underlying OpenSSL implementations, see the the OpenSSL documentation (often also available as man pages on Unix). For details of the Apple Security Framework, see the Security Framework documentation on the Apple developer site, and in particular the the Secure Transport section.
Detailed configuration of the SSL parameters can be done using the FLI, with OpenSSL or Apple Security Framework functions.
At the time of writing, OpenSSL is available as shown in OpenSSL availability:
|Availability of OpenSSL
Installed by default on most 32-bit and 64-bit distributions
32-bit and 64-bit libraries are available at
32-bit and 64-bit libraries are installed by default.
Installed by default and available via ports or pkg.
Installed by default
After installing (with pkgadd) you need to put the shared libraries
libssl.o on the loader path. By default these are installed in
To add the libraries to the loader path, either:
/usr/local/ssl/lib to the environment variable
On machines where the path is unknown or is incorrect, you must set the path by calling set-ssl-library-path, or by passing the path as the library-path argument to ensure-ssl. The default setting for Windows matches the libraries from the page that is mentioned in the table OpenSSL availability.
SSL abstract contexts are objects that represent the configuration of SSL connections. They are created by using either create-ssl-server-context or create-ssl-client-context for creating server or client SSL connections respectively. They are then passed repeatably to functions that create socket connections (instances of socket-stream or async-io-state) or to functions that attach SSL to socket connections to configure the SSL, using the keyword
See create-ssl-server-context and create-ssl-client-context for details about configuration options and their effects, and sections 25.8.4 Creating a stream with SSL and 25.8.5 Using Asynchronous I/O with SSL for the functions that take the
Abstract contexts where introduced in LispWorks 8.0. They are intended to simplify code that needs to run on both SSL mplementation (see 25.8.1 SSL implementations), and simplify performing commonly executed tasks.
There are four ways to make a socket-stream with SSL processing:
(make-instance 'socket-stream :ssl-ctx ...).
When using the OpenSSL implementation, these calls implicitly load the OpenSSL library and seed the Pseudo Random Number Generator (PRNG). When using the Apple Security Framework implementation, they implictly load the Security Framework.
(open-tcp-stream some-url 443 :ssl-ctx t)
There are three ways to make an async-io-state with SSL processing:
These calls implicitly load the OpenSSL library and seed the Pseudo Random Number Generator (PRNG).
The keyword arguments
:handshake-timeout can be be passed to create and configure socket streams and async-io-states with SSL processing. However, in LispWorks 8.0 and newer, the preferred method of configuring SSL connections is to use 25.8.3 SSL abstract contexts with
:ssl-ctx, in which case
:ssl-configure-callback are ignored, and
:ssl-side is redundant. The various interface calls for creating and configuring SSL streams and async-io-states accept these keyword arguments as shown in SSL configuration keywords.
|Keyword and Interface call
(make-instance 'socket-stream ...) and open-tcp-stream, when ssl-ctx is non-nil, call attach-ssl and pass it all the arguments. accept-tcp-connections-creating-async-io-states and create-async-io-state-and-connected-tcp-socket when ssl-ctx is non-nil attach the ssl similar to the way async-io-state-attach-ssl does.
:ssl-ctx specifies that SSL should be used, and also specifies its configuration. The value of ssl-ctx can be:
Together with ssl-side, this symbol specifies which protocol to use. ssl-ctx can be one of:
In OpenSSL implementation, LispWorks makes a new SSL_CTX object and uses it and frees it when the stream or state is closed. The interface calls also make an SSL object, uses it and frees it when the stream or state is closed. In the Apple implementation, LispWorks makes a new ssl-context-ref object, uses it and frees it when the stream or state is closed.
ssl-abstract-context was introduced in LispWorks 8.0, and we recommend that you use abstract contexts in all new code. Note that, even for the simplest case, when you can just pass
Note that when a ssl-abstract-context is used, the keywords
Specifies a range of acceptable versions. The
A foreign pointer of type ssl-ctx-pointer (OpenSSL-specific)
This corresponds to the C type
A foreign pointer of type ssl-pointer (OpenSSL-specific)
The referenced SSL is used and is not freed when the stream is closed. See the documentation for ssl-pointer for details.
A foreign pointer of type ssl-context-ref (Apple-specific)
LispWorks takes ownership of the referenced SSL context and will release it when the stream is closed. See the documentation for ssl-context-ref for details.
:ssl-side specifies which side the stream is. When ssl-ctx is a ssl-abstract-context,
:ssl-side is redundant, and if used must match the side of ssl-ctx. The value ssl-side can be one of
:both (OpenSSL only). open-tcp-stream and create-async-io-state-and-connected-tcp-socket do not take this keyword and always use
:client. For the other calls this argument defaults to
In the OpenSSL implementation, the value of ssl-side is used in three cases:
:client => …
:server => …
:both => …
:client and the other is
:server, they conflict and an error is signaled.
:server, LispWorks calls
In the Apple implementation, ssl-side is used to select the protocol side in the call to
SSLCreateContext when creating a new ssl-context-ref.
In the OpenSSL implementation, when a new SSL object is created, ssl-side is
:client and handshake-timeout is greater than 0, a handshake is performed immediately.
In the Apple implementation, a handshake is always performed immediately after attaching SSL to a socket.
:ctx-configure-callback specifies an OpenSSL-specific 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 or ssl-context-ref. This is called immediately after a new ssl-pointer or ssl-context-ref is created. If the value of ssl-ctx is a ssl-pointer, ssl-context-ref or ssl-abstract-context ssl-configure-callback is ignored. ote that abstract contexts have separate callbacks for the different implementations, and therefore it is much more convenient to use abstract contexts in code that needs this callback and is intended to be used on more than one implementation.
When a handshake is performed immediately (in the Apple implementation or in the OpenSSL implementation when ssl-side is
:client and ssl-ctx is not a ssl-pointer), handshake-timeout specifies the time in seconds to wait for the handshake to complete. If handshake-timeout is
nil (the default) then it waits indefinitely, but the underlying implementation may have its own timeout which will cause a failure after a while. If the handshake fails or times out, it is an error situation, and an error is signaled as described in 25.8.8 Errors in SSL.
In typical usage, you will create few ssl-abstract-context objects (maybe only one), configure them as appropriate for your application and the machine that it runs on, and then use one of these as ssl-ctx in all of your calls. If some connections need special configuration, you will use ssl-configure-callback in the ssl-abstract-context to configure the SSL of this connection. Sometimes when you open a connection as a client it may be sufficient to pass a symbol for ssl-ctx. Passing an ssl-pointer or ssl-context-ref as ssl-ctx is for special cases.
You can attach SSL to an existing socket-stream by calling attach-ssl on the stream. The socket-stream SSL keyword arguments are processed by attach-ssl as described in 25.8.6 Keyword arguments for use with SSL.
After an object (stream or state) has been detached, you can attach SSL to it again.
Detaching frees any automatically generated SSL objects in the same way that closing a stream or state does.
For example, if you have attached SSL to an async-io-state and then want to change to synchronous communication, you need to close the async-io-state by close-async-io-state with keep-alive true (effectively detach the SSL), and then call make-instance with socket-stream with the socket plus SSL-CTX and any other necessary arguments.
To move the other way, from synchronous to asynchronous, use replace-socket-stream-socket with socket
nil to disconnect the socket from the stream (which effectively calls detach-ssl), call create-async-io-state with the socket, and then call async-io-state-attach-ssl on the new async-io-state.
The condition can be one of the types ssl-closed, ssl-error, ssl-failure, ssl-handshake-timeout, ssl-verification-failure and ssl-x509-lookup See the manual pages for details of these condition classes.
The exact meaning of signaling a SSL error depends on the context. For synchronous socket I/O (using socket-stream), it means calling error, except when it happens inside a function that takes errorp argument (open-tcp-stream and create-ssl-socket-stream) and errorp is
nil. In the latter case, these functions return the condition object as a second value.
For asynchronous socket I/O (using async-io-state), the condition will be part of the format arguments list that is passed to callback in create-async-io-state-and-connected-tcp-socket or async-io-state-attach-ssl. You can get the condition from this list by using async-io-ssl-failure-indicator-from-failure-args. In accept-tcp-connections-creating-async-io-states, the condition will be the argument of ssl-error-callback.
See the example files in:
LispWorks® User Guide and Reference Manual - 01 Dec 2021 19:30:24