All Manuals > LispWorks® User Guide and Reference Manual > 32 The COMM Package

create-ssl-server-context

create-ssl-client-context Functions

Summary

Create an abstract SSL context that can be used as the context with different SSL implementations.

Package

comm

Signatures

create-ssl-server-context &key key-file cert-file password-callback password dh-file protocol-version implementation openssl-ctx-configure-callback openssl-ssl-configure-callback apple-configure-callback verify-callback client-hello-callback openssl-trusted-file openssl-trusted-directory apple-use-system-trusted apple-add-trusted-file apple-trust-callback keychain keychain-password keychain-reset name => ssl-abstract-context

create-ssl-client-context &key key-file cert-file password-callback password protocol-version implementation openssl-ctx-configure-callback openssl-ssl-configure-callback apple-configure-callback verify-callback cert-request-callback tlsext-host-name openssl-trusted-file openssl-trusted-directory apple-use-system-trusted apple-add-trusted-file apple-trust-callback keychain keychain-password keychain-reset name => ssl-abstract-context

Arguments
key-file
nil or a pathname designator.
cert-file
nil or a pathname designator.
password-callback
nil or a designator for a function taking one argument.
password
nil or a string.
dh-file
nil or a pathname designator.
protocol-version
A keyword or t.
implementation
A keyword or nil.
openssl-ctx-configure-callback
nil or a designator for a function taking one argument (OpenSSL specific).
openssl-ssl-configure-callback
nil or a designator for a function taking one argument (OpenSSL specific).
apple-configure-callback
nil or a designator for a function taking one argument (Apple specific).
verify-callback
nil or a designator for a function taking one argument or t, nil or :try.
client-hello-callback
nil or a designator for a function taking two arguments (Apple specific).
openssl-trusted-file
nil, :default or a pathname designator (OpenSSL specific).
openssl-trusted-directory
nil, :default or a pathname designator (OpenSSL specific).
apple-use-system-trusted
A boolean (Apple specific).
apple-add-trusted-file
nil or a pathname designator (Apple specific).
apple-trust-callback
Expert use: nil or a designator for a function taking one argument (Apple specific).
keychain
A pathname designator, :temp, :default, nil or a keychain object (Apple specific).
keychain-password
nil or a string (Apple specific).
keychain-reset
A boolean (Apple specific).
name
An object.
cert-request-callback
nil or a designator for a function taking two arguments (Apple specific).
tlsext-host-name
nil or a string.
Values
ssl-abstract-context
Description

The functions create-ssl-server-context and create-ssl-client-context create and return abstract SSL contexts of type ssl-abstract-context. They are abstract because they do not contain any SSL implementation-specific objects, allowing the implementation to be chosen later. The ssl-abstract-context can be supplied as the :ssl-ctx keyword argument to functions that attach SSL to TCP streams (mainly open-tcp-stream or create-async-io-state-and-connected-tcp-socket for the client side, and make-instance with socket-stream or accept-tcp-connections-creating-async-io-states for the server side). The object to which SSL is being attached (either a socket-stream or an async-io-state) is referred to below as the connection object, and most of the callbacks in the ssl-abstract-context are passed this connection object as an argument. When used, the ssl-abstract-context uses a specific implemenation to implement the SSL processing. The implementation may be either OpenSSL or Apple.

key-file and cert-file can be used to specify file(s) containing keys and certificates. Both must be PEM files. If cert-file is nil, then key-file is also used as the file for certificates. In the OpenSSL implementation, key-file must contain the private key (because it is passed to SSL_CTX_use_RSAPrivateKey_file) and, if cert-file is not nil, then it must contain the certificate(s) (because it is passed to SSL_CTX_use_certificate_chain_file). In the Apple implementation, the private key can also be in cert-file, in which case key-file can be nil. key-file and cert-file default to nil.

password-callback or password are used to specify the password when opening key-file and cert-file. If password-callback is non-nil then password is ignored, and when the password is required, password-callback is called with the connection object and should return the password as a string. Otherwise, if password is non-nil then it should be a string and is used as the password. password-callback and password default to nil.

When dh-file is non-nil, it specifies the DH (Diffie-Hellman) parameters. Note that only create-ssl-server-context accepts dh-file and create-ssl-client-context signals an error if dh-file is supplied. If dh-file is nil (the default) then the SSL implementation will need to compute the DH parameters itself, which takes a significant amount of time (Apple say as long as 30 seconds), so normally you should always supply dh-file. The file specified by dh-file needs to contain the DH params in either PEM or DER format.

protocol-version can be used to specify the SSL protocol version. It is interpreted in the same way that a keyword is interpreted when it is used the value for :ssl-ctx for functions such as open-tcp-stream. The default is t. See 25.8.6 Keyword arguments for use with SSL for details.

implementation allows you to force the ssl-abstract-context to always use a specific SSL implementation. If implementation is non-nil then it must be :openssl or (in macOS or iOS) :apple. If implementation is nil (the default), then LispWorks will choose an SSL implementation at the time the ssl-abstract-context is used, so it can use different implementations at different times. Supplying a non-nil value for implementation forces the ssl-abstract-context to always use a specific implementation.

openssl-ctx-configure-callback and openssl-ssl-configure-callback are OpenSSL-specific arguments. If openssl-ctx-configure-callback is non-nil then it is called with the OpenSSL SSL_CTX object (an instance of ssl-ctx-pointer, corresponding to the type SSL_CTX* in C) immediately after it is created. Note that this happens typically once per image invocation, because the ssl-ctx-pointer is created and cached the first time the ssl-abstract-context is used. If openssl-ssl-configure-callback is non-nil then it is called with each OpenSSL SSL object (an instance of ssl-pointer, corresponding to the type SSL* in C) which is created from the context. Both callbacks are called after LispWorks has applied all the configurations that are implied by the other values in the ssl-abstract-context. Note that these callbacks receive the foreign pointers of the underlying implementation (OpenSSL) as an argument, rather than the Lisp connection object that most of the other callbacks receive.

apple-configure-callback is Apple specific callback. If apple-configure-callback is non-nil then it is called with each ssl-context-ref instance that is created by the abstract context, after LispWorks has applied all the configurations that are implied by the other values in the ssl-abstract-context. Note that this callback receives the foreign pointer of the underlying implementation (Apple) as an argument, rather than the Lisp connection object that most of the other callbacks receive.

verify-callback controls the verification of certificates and defaults to t in create-ssl-client-context and to nil in create-ssl-server-context. If verify-callback is nil then the certificate is not verified and, on the server side, it also does not request a certificate from the client. If verify-callback is t then the certificate is verified, that is LispWorks (using the underlying implementation) verifies that the certificate chain is correct and the root certificate is trusted. If verify-callback is :try in create-ssl-server-context then a certificate is verified if the client sends one, but this is not required. If verify-callback is a function designator, then it is called with the connection object as an argument, and is responsible for doing all the verification and should return nil if the verification fails and non-nil if it succeeds. If the verification fails then an error of type ssl-verification-failure is signaled (see the notes below about errors). Otherwise, the handshake continues. When verify-callback is a function designator, it can call ssl-connection-verify to verify the certificate in the same way as when verify-callback is t, and then do any further checks it wants to do.

Note that to verify the certificate chain, there needs to be a list of trusted certificates that can be used as the root certificates. In the Apple implementation, these default to the built in trusted list from the operating system, but can be controlled by apple-use-system-trusted, apple-add-trusted-file and apple-trust-callback (see below). In the OpenSSL implementation, you can can control it by using openssl-trusted-file and openssl-trusted-directory (see below).

cert-request-callback can be used only in create-ssl-client-context. If cert-request-callback is non-nil then it is called on the client side with the connection object if the server side requested a certificate during the handshake. If cert-request-callback returns non-nil, then the handshake continues the certificate is sent to the server. If cert-request-callback returns nil, then an error of type ssl-verification-failure is signaled (see the notes below about errors). The certificate may have already been set for the connection using key-file or cert-file, or it may be set in cert-request-callback. If you want to set the certificate to send in cert-request-callback, you can either call ssl-connection-read-certificates or use functions from the underlying SSL implementation.

client-hello-callback can be used only in create-ssl-server-context. For the Apple implementation, it requires at least macOS version 11 or iOS version 9 to work. If client-hello-callback is non-nil then it is called on the server side at the beginning of the handshake, after the client has sent the hello message but before the server sends the certificate. client-hello-callback is called with the connection object and the server name that the client sent (in a LispWorks client, you can set this using the :tlsext-host-name argument to open-tcp-stream or create-async-io-state-and-connected-tcp-socket). If client-hello-callback returns non-nil, then the handshake continues. If client-hello-callback returns nil then an error of type ssl-verification-failure is signaled (see the notes below about errors). Typically, client-hello-callback will want to set the certificate according to the server name, which can be done either by calling ssl-connection-read-certificates or using functions from the underlying SSL implementation.

tlsext-host-name can be used only in create-ssl-client-context. If tlsext-host-name is non-nil then it specifies a default host name for the SNI extension that is sent to the server, and on the Apple implementation it also needs to match the Common Name of the certificate that the server returns for the verification to succeed. The value of tlsext-host-name can be overriden each time the abstract context is used by passing a :tlsext-host-name argument to the function that receieves the abstract context (for example open-tcp-stream). tlsext-host-name defaults to nil.

openssl-trusted-file and openssl-trusted-directory are OpenSSL-specific, and specify where to find trusted certificates that are acceptable as root certificates when verifying the peer certificate. Both default to nil, meaning no trusted certificates, which will cause any verification to fail. If either openssl-trusted-file or openssl-trusted-directory is :default, then the default file or directory (CAfile and CApath in OpenSSL) of the current OpenSSL installation is used. Note that not all OpenSSL installations install the default path or file. If openssl-trusted-file is a pathname designator then it should specify the pathname of a PEM file containing the trusted certificates. If openssl-trusted-directory is a pathname designator then it should specify the pathname of a directory containing the trusted certificates, which has to be arranged in a specific way. See the documentation of the OpenSSL function SSL_CTX_load_verify_locations for details.

apple-use-system-trusted and apple-add-trusted-file are Apple-specific, and specify the trusted certificates that are acceptable as root certificates when verifying the peer certificate. apple-use-system-trusted defaults to t, which means that the list of trusted certificates built into the OS (macOS or iOS) is used. If apple-use-system-trusted is nil, the built in list is not used. If apple-add-trusted-file is non-nil, then it should specify the pathname of a PEM file containing trusted certificates. If apple-use-system-trusted is also non-nil, both the system built in trusted certificates and the certificates in the file specified by apple-add-trusted-file are trusted, otherwise only the certificates in the file are trusted. apple-add-trusted-file defaults to nil.

apple-trust-callback is for expert use. If apple-trust-callback is non-nil, it must be a designator for a function taking one argument, a foreign pointer corresponding to the C type SecTrustRef. apple-trust-callback is called during the verification process, just before the trust is "evaluated". apple-trust-callback can then modify the SecTrustRef using C functions from the Apple Security Framework, and can also do the trust evaluation itself. If apple-trust-callback did not evaluate the trust, it must return nil, and then LispWorks will do the evaluation. If apple-trust-callback did the evaluation, it must return three values. The first value must be t (specifying that it evaluated the trust). The second value is a boolean, specifying whether the trust is accepted or rejected, and the third value is additional information about the evaluation results. The second and third values are the two values that ssl-connection-verify will return when called on a connection that was made with the ssl-abstract-context. When the ssl-abstract-context has verify-callback t, the second value is the value that is used to decide if the verification succeeded or not.

Note: the SecTrustRef passed to apple-trust-callback is a temporary object that will be released after the callback returns and the trust evaluation has completed (by a cleanup-form of an unwind-protect). If you want to keep it you need to retain it.

keychain, keychain-password and keychain-reset are Apple-specific, and are used only when key-file or cert-file are non-nil, when they specify the keychain that is used while reading these files. keychain defaults to nil, and can be one of:

nil or :temp.
LispWorks create a temporary keychain with password either keychain-password if it not nil or a random string, and then deletes the keychain after reading the files.
A pathname designator.
LispWorks opens or creates a keychain in the file specified by keychain, using keychain-password or a random string as above. If the file already exists and keychain-reset is non-nil, then the keychain is deleted first. The keychain is not deleted after use.
:default or a FLI pointer to a keychain object.
LispWorks uses the specified keychain (:default means use the default keychain). In this case the keychain is used (without trying to unlock it) and is not deleted.

name can be any Lisp Object, and is used just to name the ssl-abstract-context. name is used in printing the ssl-abstract-context, and some error messages associated with processing abstract contexts report the name of the abstract context if there is one. The name of an ssl-abstract-context can be accessed by ssl-abstract-context-name.

Notes

The functions that use a ssl-abstract-context receive it by the keyword :ssl-ctx. These functions also take other keywords to control the SSL behaviour. Of these keywords, :ctx-configure-callback and :ssl-configure-callback are ignored when a ssl-abstract-context is used, and the callbacks of the ssl-abstract-context are used instead. If :ssl-side is supplied, it must match the side of the ssl-abstract-context. If :ssl-side is not supplied then the side in the ssl-abstract-context is used. The keyword :tlsext-host-name in the receiving function overrides the value of tlsext-host-name as described above. The keyword :handshake-timeout is used as described in the documentation for the receiving function.

Abstract contexts can be used after saving the image (by save-image or deliver) and restarting. Any pointers to implementation-specific objects that are cached in the abstract context are discarded the first time it is used in a restarted image.

If the callbacks that receive the connection object need to do something different depending on which implementation is used, then they should use ssl-connection-ssl-ref to get the underlying implementation object, and then use typep, typecase or methods that specialize on the implementation specific types (ssl-pointer or ssl-context-ref).

As described for implementation above, the same ssl-abstract-context can be used to produce connections where the SSL processing is done either by OpenSSL or by the Apple Security Framework, by setting the ssl-default-implementation.

Abstract contexts try to cache implementation specific objects as much as possible, which means that the values that are passed to it may be used only once. For example, the files specified by key-file and cert-file are accessed only the first time the abstract context is used in the current image invocation.

The various callbacks in the ssl-abstract-context are called while attaching SSL to the connection object, which may or may not happen before your code "sees" the connection object. For example, if open-tcp-stream is passed an ssl-abstract-context as the :ssl-ctx argument, then the callbacks in the ssl-abstract-context will typically be called with the connection object before open-tcp-stream returns it. If there is some failure during the handshake, open-tcp-stream will never return the object that the callbacks received.

Examples

There are examples for using ssl-abstract-context in:

(example-file "ssl/ssl-certificates")
(example-file "ssl/ssl-server")
See also

ssl-abstract-context
open-tcp-stream
create-async-io-state-and-connected-tcp-socket
accept-tcp-connections-creating-async-io-states
socket-stream
async-io-state
ssl-connection-verify
ssl-default-implementation
25.8 Using SSL


LispWorks® User Guide and Reference Manual - 01 Dec 2021 19:30:26