rfc.tls
- Transport layer security ¶This module handles secure connection over TCP socket.
This module is used by rfc.http
to realize https connection
(see rfc.http
- HTTP client).
Whether the running Gauche has TLS support depends on the build
options, and can be checked with
a feature identifier gauche.net.tls
.
See Feature conditional, for more about feature identifiers.
Gauche uses MbedTLS (https://tls.mbed.org/) as TLS implementation. We used to support alternative subsystems, so the library is designed to handle multiple subsystems. In future we may support additional subsystems.
{rfc.tls
}
An abstract base class of a TLS implementation.
You can use its instance to communicate with peer over secure connection.
You usually don’t need to care the concrete subclass; just treat
their instances as <tls>
instance.
This inherits <connection>
(see gauche.connection
- Connection framework).
{rfc.tls
}
A class that implements MbedTLS subsystem interface.
{rfc.tls
}
The default TLS subsystem to be used. In the current version,
it may just be <mbed-tls>
, or #f
if the system is not
compiled with TLS support.
{rfc.tls
}
Creates and returns a new TLS instance of the class default-tls-class
.
The returned TLS instance can be used either as a client, by passing it
to tls-connect
, or as a server, by passing it to tls-bind
and tls-accept
. See the following subsections for each usage.
The arguments must be a keyword-value list, and passed to the constructor of the TLS class. The following keyword arguments are recognized.
:server-name
Server name to be used for TLS Server Name Indication extension. In general, if you use the created TLS object as a client, you want to specify the server name. If you use the create TLS object as a server, you can omit this option.
:skip-verification
Client only. If the argument is true, skip server certificate verification upon connection. This is unsafe and should not be used except experimental purposes.
{rfc.tls
}
Shuts down the underling connection. The peer will notified
the connection is closed.
Once tls is closed, it can no longer be used.
You can also call connection-close
on tls to get the same effect
(see gauche.connection
- Connection framework).
{rfc.tls
}
If tls is connected, they return input and output port to communicate
with the peer, respectively.
If tls is not connected, #f
is returned.
You can also call connection-input-port
and connection-output-port
on tls got get the same efffect
(see gauche.connection
- Connection framework).
{rfc.tls
}
Wait for tls to be ready for reading or writing. The tls object must
be already bound or connected; otherwise, it immediately returns ()
.
The rw argument is a list of symbols read
and/or write
,
to specify what condition(s) to be checked. The timeout argument
is either a <time>
object to specify an absolute time point,
a real number to specify the number of seconds from the current time,
or #f
to wait indefinitely. If omitted, #f
is assumed.
The return value is a list of symbols that are satisfied. That is,
if you pass (read)
or (read write)
in rw and the
tls communication is ready to read, (read)
is returned.
If timeout reaches before any condition is met, ()
is returned.
{rfc.tls
}
This is for troubleshooting. Set the global debug log level of
the TLS subsystem to level, which is an exact integer between
0 (no debug logging, default) to 9 (maximum debug logging).
The actual granularity of log levels depends on the TLS subsystem, and 0-9 scale is mapped to each subsystem’s logging mechanism. You want some experiment to find appropriate value.
When your code is a client to connect to a server over TLS,
you need CA certificates to verify server certificates properly.
Gauche doesn’t have its own CA certificates, and relies on the
system’s certificate store by default. On Unix-based systems,
we search several known locations: On popular Linux distributions
we recommend you to install ca-certificates
package (or similar one).
On OSX, we recommend to install openssl via Homebrew. On Windows,
we use system’s certificate store via Wincrypt API.
With the default configuration, Gauche checks the availability of the system’s certificate store at initilization and use one if available. You can explicitly give the path of CA certificate bundle, or disable it and provide individual certificate per connection.
If, for some reasons, you cannot install system-wide CA certificate bundle, you can also download Curl’s CA certificate bundle https://curl.haxx.se/ca/cacert.pem, and install it in Gauche installation directory. We have a convenience script. After installing Gauche, run the following command:
gosh tools/get-cacert
You need curl installed on your system. If you’ve installed Gauche with root priviledge, you’ll be asked sudo password to install the CA bundle file.
If you decided to do this, make sure you run the above command occasionally to get updated CA certificate bundles, for certificates may expire or be revoked.
{rfc.tls
}
Holds CA certificate bundle to be used. The value
can be either a string path to a CA bundle file, a symbol system
,
or #f
.
If it is system
, Gauche uses system’s default bundle.
An error is signaled on connection
if Gauche can’t find one.
If it is #f
, CA certificate won’t be loaded automatically,
and you have to manually load one using tls-load-object
.
(Note: This option is only valid with <ax-tls>
. If you’re using
<mbed-tls>
, you need valid CA certificate bundle.)
With the default configuration, Gauche scans the system CA bundle
when rfc.tls
module is initialized, and if it finds one,
tls-ca-bundle-path
is set to system
; otherwise,
tls-ca-bundle-path
is set to #f
. So if you’re using
with default configuration and you see its value is system
,
you can count on the system CA certificate bundle.
This default behavior may be altered if Gauche is configured
with --with-ca-bundle
option. You can execute
gauche-config --reconfigure
command to see if
special --with-ca-bundle
option is given.
{rfc.tls
}
Establishes TLS connection as a client.
The tls argument must be an unconnected TLS object. The
host and port arguments are strings to specify
server’s hostname and port. Besides the common hostname, IP notation
(e.g. "127.0.0.1"
or "[::1]"
) are allowed in host.
Integre port number or a service name (e.g. "https"
)
are allowed in port.
The proto argument must be either one of the symbols
tcp
or udp
. If omitted, tcp
is assumed.
(If it is udp
, DTLS is used instead of TLS. However, we still
lack some additional API support to make DTLS usable.)
Once the procedure contacted to the server,
it obtains its server certificate and tries to validate it
against the known CA certificates. If the server can’t be validated,
an error is signaled. To establish a proper connection,
a CA certificate storage must be specified
by the parameter tls-ca-bundle-path
.
Once the connection is established and TLS handshake is succeeded, the passed tls becomes ’connected’ state and can be used to read/write data from/to the connected peer.
To open a TLS connection as a server, you have to prepare a private key, a server certificate, and intermediate certificates. Those must be loaded before accepting TLS connections from clients.
{rfc.tls
}
Read and register server certifcate(s) stored in a file named by path.
The given file may contain multiple certificates. You can call this
multiple times to add intermediate certifictes.
{rfc.tls
}
Read and register server private key storead in a file named by path,
with the password. If the private key file is not encrypted,
you can pass #f
to password.
{rfc.tls
}
Creates a server endpoint of tls connection.
The tls argument must be an unconnected, unbound TLS object.
The host argument may be a string hostname or #f
.
The port argument is an integer or a string to specify the port.
The proto argument must be either one of the symbols
tcp
or udp
, and assumed tcp
if omitted.
(NB: udp server (DTLS) needs some more API support, so
it is not very usable now.)
Like socket-bind
, you can give 0 to port to let the
system choose an available port number. The actual port number
can be obtained by
(sockaddr-port (connection-self-address tls))
.
{rfc.tls
}
The passed tls object must already be bound by tls-bind
.
Server certificates and private key must be already loaded to tls
by tls-load-certificate
and tls-load-private-key
.
This waits for a client to connect to the bound endpoint. Once a client tries to connect, it present the server certificate and performs TLS handshake. If everything succeeds, returns a fresh tls object that can be used to read/write dat from/to the connected peer.
Since <tls>
class implements connection framework
(see gauche.connection
- Connection framework), the following methods
can be called on a tls object. Notably, the first two
can be used to obtain IP address of the underlying connection.
connection-self-address (c <tls) connection-peer-address (c <tls>) connection-input-port (c <tls>) connection-output-port (c <tls>) connection-close (c <tls>)