By default cl+ssl searches for OpenSSL shared libraries
in platform-dependent default locations.
To explicitly specify what to load, use the cl+ssl/config
module before loading cl+ssl:
(ql:quickload "cl+ssl/config")
(cl+ssl/config:define-libssl-path "/opt/local/lib/libssl.dylib")
(cl+ssl/config:define-libcrypto-path "/opt/local/lib/libcrypto.dylib")
(ql:quickload "cl+ssl")
The PATH parameter of those two macros is not evaluated.
This is dictated by CFFI. So either use a literal
or compute it at the macro-expansion time.
You may need to rebuild cl+ssl for the changed paths to have effect.
This depends on CFFI and the FFI implementation of your Lisp.
Macro define-libssl-path (path)
Define the path where libssl resides to be PATH (not evaluated). This
macro should be used before loading CL+SSL.
Macro define-libcrypto-path (path)
Define the path where libcrypto resides to be PATH (not evaluated). This
macro should be used before loading CL+SSL.
Function make-ssl-client-stream (socket &key (unwrap-stream-p *default-unwrap-stream-p*) hostname close-callback external-format (verify (if (ssl-check-verify-p) :optional *make-ssl-client-stream-verify-default*)) alpn-protocols certificate key password (cipher-list *default-cipher-list*) method (buffer-size *default-buffer-size*) (input-buffer-size buffer-size) (output-buffer-size buffer-size))
Performs TLS/SSL handshake over the specified SOCKET using
the SSL_connect OpenSSL function and returns a Lisp stream that
uses OpenSSL library to encrypt the output data when sending
it to the socket and to decrypt the input received.
Uses a global SSL_CTX instance, which can be overriden
by WITH-GLOBAL-CONTEXT. (The global SSL_CTX is
passed as a parameter to an internall call of SSL_new.)
SOCKET - represents the socket to be wrapped into an SSL stream.
Can be either a Lisp stream (of an implementation-dependent type) for that
socket, or an integer file descriptor of that socket. If that's a
stream, it will be closed automatically when the SSL stream
is closed. Also, on CCL, (CCL:STREAM-DEADLINE SOCKET) will be used
as a deadline for 'socket BIO' mode.
See README.md / Usage / Timeouts and Deadlines for more information.
If that's a file descriptor, it is not closed automatically
(you can use CLOSE-CALLBACK to arrange for that).
UNWRAP-STREAM-P - if true, (STREAM-FD SOCKET) will be attempted
to extract the file descriptor. Otherwise the SOCKET
is left as is. Anyway, if in result we end up with an integer
file descriptor, a socket BIO is used; if we end up with a
stream - Lisp BIO is used. This parameter defaults to
*DEFAULT-UNWRAP-STREAM-P* which is initalized to true.
See README.md / Usage for more information on BIO types.
HOSTNAME if specified, will be sent by client during TLS negotiation,
according to the Server Name Indication (SNI) extension to the TLS.
If we connect to a server handling multiple domain names,
this extension enables such server to choose certificate for the
right domain. Also the HOSTNAME is used for hostname verification
(if verification is enabled by VERIFY).
CLOSE-CALLBACK - a function to be called when the created
ssl stream is CL:CLOSE'ed. The only argument is this ssl stream.
EXTERNAL-FORMAT - if NIL (the default), a plain (UNSIGNED-BYTE 8)
ssl stream is returned. With a non-NIL external-format, a flexi-stream
capable of character I/O will be returned instead, with the specified
value as its initial external format.
VERIFY can be specified either as NIL if no check should be performed,
:OPTIONAL to verify the server's certificate if server presents one or
:REQUIRED to verify the server's certificate and fail if an invalid
or no certificate was presented. Defaults to
*MAKE-SSL-CLIENT-STREAM-VERIFY-DEFAULT* which is initialized
to :REQUIRED
The verification includes verifying the HOSTNAME against the server
ceritificate, using the VERIFY-HOSTNAME function.
An error is signalled in case of the certificate or hostname
verification failure.
Note, the VERIFY logic expects that the global
SSL_CTX object does not have the SSL_VERIFY_PEER
flag enabled - the default for the cl+ssl's global SSL_CTX.
If the current global SSL_CTX object has SSL_VERIFY_PEER enabled,
the SSL_Connect will perform certificate (but not hostname)
verification on its own, and an error will be signalled for a
bad certificate even with :VERIFY NIL.
ALPN-PROTOCOLS, if specified, should be a list of alpn protocol names,
such as "h2", that will be offered to the server. The protocol
selected by the server can be retrieved with
GET-SELECTED-ALPN-PROTOCOL.
CERTIFICATE is the path to a file containing a PEM-encoded certificate.
Note, if one certificate will be used for multiple TLS connections,
it's better to load it into a common SSL_CTX (context) object rather
than reading it for every new connection.
KEY is the path to a PEM-encoded private key file of that certificate.
PASSWORD the password to use for decryptipon of the KEY (if encrypted).
CIPHER-LIST - If not NIL, must be a string to pass to SSL_set_cipher_list.
An ERROR is signalled if SSL_CTX_set_cipher_list fails.
Defaults to *DEFAULT-CIPHER-LIST* which is initialized to NIL.
METHOD - usually you want to leave the default value. It is used
to compute the parameter for OpenSSL function SSL_CTX_new when
creating the global SSL_CTX object for cl+ssl. This parameter only has
effect on the first call, when the global SSL_CTX is not yet created.
The default value is TLS_method on OpenSSL > 1.1.0 and SSLv23_method
for older OpenSSL versions.
BUFFER-SIZE - default value for both the INPUT-BUFFER-SIZE and
OUTPUT-BUFFER-SIZE parameters. In turn defaults to the
*DEFAULT-BUFFER-SIZE* special variable.
INPUT-BUFFER-SIZE - size of the input buffer of the ssl stream.
Defaults to the BUFFER-SIZE parameter.
OUTPUT-BUFFER-SIZE - size of the output buffer of the ssl stream.
Defaults to the BUFFER-SIZE parameter.
Function make-ssl-server-stream (socket &key (unwrap-stream-p *default-unwrap-stream-p*) close-callback external-format certificate key password (cipher-list *default-cipher-list*) method (buffer-size *default-buffer-size*) (input-buffer-size buffer-size) (output-buffer-size buffer-size))
Performs server-side TLS handshake over the specified SOCKET using
the SSL_accept OpenSSL function and returns a Lisp stream that
uses OpenSSL library to encrypt the output data when sending
it to the socket and to decrypt the input received.
Uses a global SSL_CTX instance, which can be overriden
by WITH-GLOBAL-CONTEXT. (The global SSL_CTX is
passed as a parameter to an internall call of SSL_new.)
All parameters have the same meaning as documented
for MAKE-SSL-CLIENT-STREAM.
Macro with-global-context ((ssl-ctx &key auto-free-p) &body body)
Executes the BODY with *SSL-GLOBAL-CONTEXT* bound to the SSL-CTX.
If AUTO-FREE-P is true the context is freed using SSL-CTX-FREE before exit.
Function make-context (&key (method nil method-supplied-p) disabled-protocols (options (list +ssl-op-all+)) min-proto-version (session-cache-mode +ssl-sess-cache-server+) (verify-location :default) (verify-depth 100) (verify-mode +ssl-verify-peer+) verify-callback cipher-list (pem-password-callback 'pem-password-callback) certificate-chain-file private-key-file private-key-password (private-key-file-type +ssl-filetype-pem+))
Creates a new SSL_CTX using SSL_CTX_new and initializes it according to
the specified parameters.
After you're done using the context, don't forget to free it using SSL-CTX-FREE.
Exceptions:
SSL-ERROR-INITIALIZE. When underlying SSL_CTX_new fails.
Keyword arguments:
METHOD. Specifies which supported SSL/TLS to use.
If not specified then TLS_method is used on OpenSSL
versions supporing it (on legacy versions SSLv23_method is used).
DISABLED-PROTOCOLS. List of +SSL-OP-NO-* constants. Denotes
disabled SSL/TLS versions. When METHOD not specified
defaults to (LIST +SSL-OP-NO-SSLV2+ +SSL-OP-NO-SSLV3+)
OPTIONS. SSL context options list. Defaults to (list +SSL-OP-ALL+)
SESSION-CACHE-MODE. Enable/Disable session caching.
Defaults to +SSL-SESS-CACHE-SERVER+
VERIFY-LOCATION. Location(s) to load CA from.
Possible values:
:DEFAULT - SSL_CTX_set_default_verify_paths will be called.
:DEFAULT-FILE - SSL_CTX_set_default_verify_file will be called. Requires OpenSSL >= 1.1.0.
:DEFAULT-DIR - SSL_CTX_set_default_verify_dir will be called. Requires OpenSSL >= 1.1.0.
A STRING or a PATHNAME - will be passed to SSL_CTX_load_verify_locations
as file or dir argument depending on wether it's really
a file or a dir. Must exist on the file system and be available.
A LIST - each value assumed to be either a STRING or a PATHNAME and
will be passed to SSL_CTX_load_verify_locations as described above.
VERIFY-DEPTH. Sets the maximum depth for the certificate chain verification
that shall be allowed for context. Defaults to 100.
VERIFY-MODE. The mode parameter to SSL_CTX_set_verify.
Defaults to +VERIFY-PEER+
VERIFY-CALLBACK. The verify_callback parameter to SSL_CTX_set_verify.
Please note: if specified, must be a CFFI callback i.e. defined as
(DEFCALLBACK :INT ((OK :INT) (SSL-CTX :POINTER)) .. ).
CIPHER-LIST. If specified, must be a string to pass to SSL_CTX_set_cipher_list.
An ERROR is signalled if SSL_CTX_set_cipher_list fails.
PEM-PASSWORD-CALLBACK. Sets the default password callback called when
loading/storing a PEM certificate with encryption.
Please note: this must be CFFI callback i.e. defined as
(CFFI:DEFCALLBACK :INT ((BUF :POINTER) (SIZE :INT) (RWFLAG :INT) (UNUSED :POINTER)) .. ).
Defaults to PEM-PASSWORD-CALLBACK which simply uses password
provided by WITH-PEM-PASSWORD.
CFFI function (ssl-ctx-free "SSL_CTX_free") ((ctx ssl-ctx)) => :void
Function use-certificate-chain-file (certificate-chain-file)
Applies OpenSSL function SSL_CTX_use_certificate_chain_file
to the cl+ssl's global SSL_CTX object and the specified
CERTIFICATE-CHAIN-FILE.
OpenSSL requires the certificates in the file to be sorted
starting with the subject's certificate (actual client or
server certificate), followed by intermediate CA certificates
if applicable, and ending at the highest level (root) CA.
Note: the RELOAD function clears the global context and in particular
the loaded certificate chain.
Function ssl-load-global-verify-locations (&rest pathnames)
PATHNAMES is a list of pathnames to PEM files containing server and CA certificates.
Install these certificates to use for verifying on all SSL connections.
After RELOAD, you need to call this again.
Function ssl-set-global-default-verify-paths ()
Load the system default verification certificates.
After RELOAD, you need to call this again.
Macro with-pem-password ((password) &body body)
Function get-selected-alpn-protocol (ssl-stream)
A wrapper around SSL_get0_alpn_selected.
Returns the ALPN protocol selected by server, or NIL if none was selected.
SSL-STREAM is the client ssl stream returned by make-ssl-client-stream.
Function decode-certificate-from-file (path &key format)
Generic function decode-certificate (format bytes)
The BYTES must be created by CFFI:MAKE-SHAREABLE-BYTE-VECTOR (because
we are going to pass them to CFFI:WITH-POINTER-TO-VECTOR-DATA)
Method decode-certificate ((format (eql :der)) bytes)
Function ssl-stream-x509-certificate (ssl-stream)
CFFI function (x509-free "X509_free") ((x509 :pointer)) => :void
Function certificate-not-after-time (certificate)
Returns a universal-time representing the time after
which the CERTIFICATE is not valid. Signals an ERROR if the
CERTIFICATE does not have a properly formatted time.
Function certificate-not-before-time (certificate)
Returns a universal-time representing the time before
which the CERTIFICATE is not valid. Signals an ERROR if
the CERTIFICATE does not have a properly formatted time.
Function certificate-subject-common-names (cert)
Function certificate-fingerprint (certificate &optional (algorithm :sha1))
Return the fingerprint of CERTIFICATE as a byte-vector. ALGORITHM is a string
designator for the digest algorithm to use (it defaults to SHA-1).
Function verify-hostname (cert hostname)
Verifies the HOSTNAME against the specified
CERT. Implemented for all OpenSSL versions,
using custom Lisp code (without relying on the functions
provided by newer OpenSSl versions, like SSL_set_verify).
Signals an error in case of verification failure.
Otherwise returns true
Function reload ()
If you save your application as a Lisp image,
call this function when that image is loaded,
to perform the necessary CL+SSL re-initialization
(unless your lisp implementation automatically
re-loads foreign libraries and preserves their
memory accross image reloads).
This should work fine if the location and version of the
OpenSSL shared libraries have not changed.
If they have changed, you may get errors, as users report:
https://github.com/cl-plus-ssl/cl-plus-ssl/issues/167
Generic function stream-fd (stream)
The STREAM's file descriptor as an integer,
if known / implemented for the current lisp.
Otherwise the STREAM itself. The result of this function can be
passed to MAKE-SSL-CLIENT-STREAM and MAKE-SSL-SERVER-STREAM.
Function random-bytes (count)
Generates COUNT cryptographically strong pseudo-random bytes. Returns
the bytes as a SIMPLE-ARRAY with ELEMENT-TYPE '(UNSIGNED-BYTE 8). Signals
an ERROR in case of problems; for example, when the OpenSSL random number
generator has not been seeded with enough randomness to ensure an
unpredictable byte sequence.
Function ensure-initialized (&key method (rand-seed nil))
In most cases you do *not* need to call this function, because it
is called automatically by all other functions. The only reason to
call it explicitly is to supply the RAND-SEED parameter. In this case
do it before calling any other functions.
Keyword arguments:
METHOD - just leave the default value.
RAND-SEED - an octet sequence to initialize OpenSSL random
number generator. On many platforms, including Linux and
Windows, it may be left NIL (default), because OpenSSL
initializes the random number generator from OS specific
service. But, for example, on Solaris it may be necessary
to supply this value. The minimum length required by OpenSSL
is 128 bits.
See http://www.openssl.org/support/faq.html#USER1 for details.
Hint: do not use Common Lisp RANDOM function to generate
the RAND-SEED, because the function usually returns
predictable values.
Variable *default-cipher-list*
Variable *default-buffer-size*
The default size for input and output buffers of SSL-STREAM objects
Variable *make-ssl-client-stream-verify-default*
Helps to mitigate the change in default behaviour of
MAKE-SSL-CLIENT-STREAM - previously it worked as if :VERIFY NIL
but then :VERIFY :REQUIRED became the default on non-Windows platforms.
Change this variable if you want the previous behaviour.
Variable *default-unwrap-stream-p*
Default value for UNWRAP-STREAM-P function parameter.
If true (the default), cl+ssl will try to extract file descriptor
from the given TCP Lisp stream and tell OpenSSL to use a socket BIO
based on that file descriptor;
otherwise use a Lisp BIO wrapping the TCP Lisp stream.
Condition ssl-error-verify
This condition is signalled on SSL connection when a peer certificate doesn't verify.
Condition ssl-error-initialize
Reader ssl-error-stream ((ssl-error-verify ssl-error-verify))
The SSL stream whose peer certificate didn't verify.
Reader ssl-error-code ((ssl-error-verify ssl-error-verify))
The peer certificate verification error code
(as returned by functions like SSL_get_verify_result or X509_STORE_CTX_get_error).
Variable +ssl-verify-none+
Variable +ssl-verify-peer+
Variable +ssl-verify-fail-if-no-peer-cert+
Variable +ssl-verify-client-once+
Variable +ssl-op-no-sslv2+
Variable +ssl-op-no-sslv3+
Variable +ssl-op-no-tlsv1+
Variable +ssl-op-no-tlsv1-1+
Variable +ssl-op-no-tlsv1-2+
Variable +ssl-sess-cache-off+
No session caching for client or server takes place.
Variable +ssl-sess-cache-client+
Client sessions are added to the session cache.
As there is no reliable way for the OpenSSL library to know whether a session should be reused
or which session to choose (due to the abstract BIO layer the SSL engine does not have details
about the connection), the application must select the session to be reused by using the
SSL-SET-SESSION function. This option is not activated by default.
Variable +ssl-sess-cache-server+
Server sessions are added to the session cache.
When a client proposes a session to be reused, the server looks for the corresponding session
in (first) the internal session cache (unless +SSL-SESS-CACHE-NO-INTERNAL-LOOKUP+ is set), then
(second) in the external cache if available. If the session is found, the server will try to
reuse the session. This is the default.
Variable +ssl-sess-cache-both+
Enable both +SSL-SESS-CACHE-CLIENT+ and +SSL-SESS-CACHE-SERVER+ at the same time.
Variable +ssl-sess-cache-no-auto-clear+
Normally the session cache is checked for expired sessions every 255 connections using the
SSL-CTX-FLUSH-SESSIONS function. Since this may lead to a delay which cannot be controlled,
the automatic flushing may be disabled and SSL-CTX-FLUSH-SESSIONS can be called explicitly
by the application.
Variable +ssl-sess-cache-no-internal-lookup+
By setting this flag, session-resume operations in an SSL/TLS server will not automatically
look up sessions in the internal cache, even if sessions are automatically stored there.
If external session caching callbacks are in use, this flag guarantees that all lookups are
directed to the external cache. As automatic lookup only applies for SSL/TLS servers, the flag
has no effect on clients.
Variable +ssl-sess-cache-no-internal-store+
Depending on the presence of +SSL-SESS-CACHE-CLIENT+ and/or +SSL-SESS-CACHE-SERVER+, sessions
negotiated in an SSL/TLS handshake may be cached for possible reuse. Normally a new session is
added to the internal cache as well as any external session caching (callback) that is configured
for the SSL_CTX. This flag will prevent sessions being stored in the internal cache (though the
application can add them manually using SSL-CTX-ADD-SESSION). Note: in any SSL/TLS servers where
external caching is configured, any successful session lookups in the external cache (ie. for
session-resume requests) would normally be copied into the local cache before processing continues
- this flag prevents these additions to the internal cache as well.
Variable +ssl-sess-cache-no-internal+
Enable both +SSL-SESS-CACHE-NO-INTERNAL-LOOKUP+ and +SSL-SESS-CACHE-NO-INTERNAL-STORE+ at the same time.
Function ssl-check-verify-p ()
DEPRECATED. Use the (MAKE-SSL-CLIENT-STREAM .. :VERIFY ?) to enable/disable verification.
Also, MAKE-CONTEXT has :VERIFY-MODE option.
Return true if SSL connections will error if the certificate doesn't verify.
Function (setf ssl-check-verify-p) (check-verify-p)
DEPRECATED. Use the (MAKE-SSL-CLIENT-STREAM .. :VERIFY ?) to enable/disable verification.
Also, MAKE-CONTEXT has :VERIFY-MODE option.
If CHECK-VERIFY-P is true, signal connection errors if the server certificate doesn't verify.