|
Packit Service |
4684c1 |
@node How to use GnuTLS in applications
|
|
Packit Service |
4684c1 |
@chapter How to use @acronym{GnuTLS} in applications
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@menu
|
|
Packit Service |
4684c1 |
* Introduction to the library::
|
|
Packit Service |
4684c1 |
* Preparation::
|
|
Packit Service |
4684c1 |
* Session initialization::
|
|
Packit Service |
4684c1 |
* Associating the credentials::
|
|
Packit Service |
4684c1 |
* Setting up the transport layer::
|
|
Packit Service |
4684c1 |
* TLS handshake::
|
|
Packit Service |
4684c1 |
* Data transfer and termination::
|
|
Packit Service |
4684c1 |
* Buffered data transfer::
|
|
Packit Service |
4684c1 |
* Handling alerts::
|
|
Packit Service |
4684c1 |
* Priority Strings::
|
|
Packit Service |
4684c1 |
* Selecting cryptographic key sizes::
|
|
Packit Service |
4684c1 |
* Advanced topics::
|
|
Packit Service |
4684c1 |
@end menu
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node Introduction to the library
|
|
Packit Service |
4684c1 |
@section Introduction
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
This chapter tries to explain the basic functionality of the current GnuTLS
|
|
Packit Service |
4684c1 |
library. Note that there may be additional functionality not discussed here
|
|
Packit Service |
4684c1 |
but included in the library. Checking the header files in @file{/usr/include/gnutls/}
|
|
Packit Service |
4684c1 |
and the manpages is recommended.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@menu
|
|
Packit Service |
4684c1 |
* General idea::
|
|
Packit Service |
4684c1 |
* Error handling::
|
|
Packit Service |
4684c1 |
* Common types::
|
|
Packit Service |
4684c1 |
* Debugging and auditing::
|
|
Packit Service |
4684c1 |
* Thread safety::
|
|
Packit Service |
4684c1 |
* Running in a sandbox::
|
|
Packit Service |
4684c1 |
* Sessions and fork::
|
|
Packit Service |
4684c1 |
* Callback functions::
|
|
Packit Service |
4684c1 |
@end menu
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node General idea
|
|
Packit Service |
4684c1 |
@subsection General idea
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
A brief description of how @acronym{GnuTLS} sessions operate is shown
|
|
Packit Service |
4684c1 |
at @ref{fig-gnutls-design}. This section will become more clear when it
|
|
Packit Service |
4684c1 |
is completely read.
|
|
Packit Service |
4684c1 |
As shown in the figure, there is a read-only global state that is
|
|
Packit Service |
4684c1 |
initialized once by the global initialization function. This global
|
|
Packit Service |
4684c1 |
structure, among others, contains the memory allocation functions
|
|
Packit Service |
4684c1 |
used, structures needed for the @acronym{ASN.1} parser and depending
|
|
Packit Service |
4684c1 |
on the system's CPU, pointers to hardware accelerated encryption functions. This
|
|
Packit Service |
4684c1 |
structure is never modified by any @acronym{GnuTLS} function, except
|
|
Packit Service |
4684c1 |
for the deinitialization function which frees all allocated memory
|
|
Packit Service |
4684c1 |
and must be called after the program has permanently
|
|
Packit Service |
4684c1 |
finished using @acronym{GnuTLS}.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@float Figure,fig-gnutls-design
|
|
Packit Service |
4684c1 |
@image{gnutls-internals,12cm}
|
|
Packit Service |
4684c1 |
@caption{High level design of GnuTLS.}
|
|
Packit Service |
4684c1 |
@end float
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The credentials structures are used by the authentication methods, such
|
|
Packit Service |
4684c1 |
as certificate authentication. They store certificates, privates keys,
|
|
Packit Service |
4684c1 |
and other information that is needed to prove the identity to the peer,
|
|
Packit Service |
4684c1 |
and/or verify the identity of the peer. The information stored in
|
|
Packit Service |
4684c1 |
the credentials structures is initialized once and then can be
|
|
Packit Service |
4684c1 |
shared by many @acronym{TLS} sessions.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
A @acronym{GnuTLS} session contains all the required state and
|
|
Packit Service |
4684c1 |
information to handle one secure connection. The session communicates with the
|
|
Packit Service |
4684c1 |
peers using the provided functions of the transport layer.
|
|
Packit Service |
4684c1 |
Every session has a unique session ID shared with the peer.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Since TLS sessions can be resumed, servers need a
|
|
Packit Service |
4684c1 |
database back-end to hold the session's parameters. Every
|
|
Packit Service |
4684c1 |
@acronym{GnuTLS} session after a successful handshake calls the
|
|
Packit Service |
4684c1 |
appropriate back-end function (see @ref{resume})
|
|
Packit Service |
4684c1 |
to store the newly negotiated session. The session
|
|
Packit Service |
4684c1 |
database is examined by the server just after having received the
|
|
Packit Service |
4684c1 |
client hello@footnote{The first message in a @acronym{TLS} handshake},
|
|
Packit Service |
4684c1 |
and if the session ID sent by the client, matches a stored session,
|
|
Packit Service |
4684c1 |
the stored session will be retrieved, and the new session will be a
|
|
Packit Service |
4684c1 |
resumed one, and will share the same session ID with the previous one.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node Error handling
|
|
Packit Service |
4684c1 |
@subsection Error handling
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
There two types of @acronym{GnuTLS} functions. The first type returns
|
|
Packit Service |
4684c1 |
a boolean value, true (non-zero) or false (zero) value; these functions
|
|
Packit Service |
4684c1 |
are defined to return an unsigned integer type. The other type returns a
|
|
Packit Service |
4684c1 |
signed integer type with zero (or a positive number) indicating
|
|
Packit Service |
4684c1 |
success and a negative value indicating failure. For the latter
|
|
Packit Service |
4684c1 |
type it is recommended to check for errors as following.
|
|
Packit Service |
4684c1 |
@example
|
|
Packit Service |
4684c1 |
ret = gnutls_function();
|
|
Packit Service |
4684c1 |
if (ret < 0) @{
|
|
Packit Service |
4684c1 |
return -1;
|
|
Packit Service |
4684c1 |
@}
|
|
Packit Service |
4684c1 |
@end example
|
|
Packit Service |
4684c1 |
The above example checks for a failure condition rather than
|
|
Packit Service |
4684c1 |
for explicit success (e.g., equality to zero). That has the advantage
|
|
Packit Service |
4684c1 |
that future extensions of the API can be extended to provide
|
|
Packit Service |
4684c1 |
additional information via positive returned values (see for example
|
|
Packit Service |
4684c1 |
@funcref{gnutls_certificate_set_x509_key_file}).
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
For certain operations such as TLS handshake and TLS packet receive
|
|
Packit Service |
4684c1 |
there is the notion of fatal and non-fatal error codes.
|
|
Packit Service |
4684c1 |
Fatal errors terminate the TLS session immediately and further sends
|
|
Packit Service |
4684c1 |
and receives will be disallowed. Such an example is
|
|
Packit Service |
4684c1 |
@code{GNUTLS_@-E_@-DECRYPTION_@-FAILED}. Non-fatal errors may warn about
|
|
Packit Service |
4684c1 |
something, i.e., a warning alert was received, or indicate the some
|
|
Packit Service |
4684c1 |
action has to be taken. This is the case with the error code
|
|
Packit Service |
4684c1 |
@code{GNUTLS_@-E_@-REHANDSHAKE} returned by @funcref{gnutls_record_recv}.
|
|
Packit Service |
4684c1 |
This error code indicates that the server requests a re-handshake. The
|
|
Packit Service |
4684c1 |
client may ignore this request, or may reply with an alert. You can
|
|
Packit Service |
4684c1 |
test if an error code is a fatal one by using the
|
|
Packit Service |
4684c1 |
@funcref{gnutls_error_is_fatal}.
|
|
Packit Service |
4684c1 |
All errors can be converted to a descriptive string using @funcref{gnutls_strerror}.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
If any non fatal errors, that require an action, are to be returned by
|
|
Packit Service |
4684c1 |
a function, these error codes will be documented in the function's
|
|
Packit Service |
4684c1 |
reference. For example the error codes @code{GNUTLS_@-E_@-WARNING_@-ALERT_@-RECEIVED} and @code{GNUTLS_@-E_@-FATAL_@-ALERT_@-RECEIVED}
|
|
Packit Service |
4684c1 |
that may returned when receiving data, should be handled by notifying the
|
|
Packit Service |
4684c1 |
user of the alert (as explained in @ref{Handling alerts}).
|
|
Packit Service |
4684c1 |
See @ref{Error codes}, for a description of the available error codes.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node Common types
|
|
Packit Service |
4684c1 |
@subsection Common types
|
|
Packit Service |
4684c1 |
@cindex gnutls_datum_t
|
|
Packit Service |
4684c1 |
@cindex giovec_t
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
All strings that are to provided as input to @acronym{GnuTLS} functions
|
|
Packit Service |
4684c1 |
should be in UTF-8 unless otherwise specified. Output strings are also
|
|
Packit Service |
4684c1 |
in UTF-8 format unless otherwise specified. When functions take as input
|
|
Packit Service |
4684c1 |
passwords, they will normalize them using @xcite{RFC7613} rules (since
|
|
Packit Service |
4684c1 |
GnuTLS 3.5.7).
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
When data of a fixed size are provided to @acronym{GnuTLS} functions then
|
|
Packit Service |
4684c1 |
the helper structure @code{gnutls_datum_t} is often used. Its definition is
|
|
Packit Service |
4684c1 |
shown below.
|
|
Packit Service |
4684c1 |
@verbatim
|
|
Packit Service |
4684c1 |
typedef struct
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
unsigned char *data;
|
|
Packit Service |
4684c1 |
unsigned int size;
|
|
Packit Service |
4684c1 |
} gnutls_datum_t;
|
|
Packit Service |
4684c1 |
@end verbatim
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
In functions where this structure is a returned type, if the function succeeds,
|
|
Packit Service |
4684c1 |
it is expected from the caller to use @code{gnutls_free()} to deinitialize the
|
|
Packit Service |
4684c1 |
data element after use, unless otherwise specified. If the function fails, the
|
|
Packit Service |
4684c1 |
contents of the @code{gnutls_datum_t} should be considered undefined and must
|
|
Packit Service |
4684c1 |
not be deinitialized.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Other functions that require data for scattered read use a structure similar
|
|
Packit Service |
4684c1 |
to @code{struct iovec} typically used by @funcintref{readv}. It is shown
|
|
Packit Service |
4684c1 |
below.
|
|
Packit Service |
4684c1 |
@verbatim
|
|
Packit Service |
4684c1 |
typedef struct
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
void *iov_base; /* Starting address */
|
|
Packit Service |
4684c1 |
size_t iov_len; /* Number of bytes to transfer */
|
|
Packit Service |
4684c1 |
} giovec_t;
|
|
Packit Service |
4684c1 |
@end verbatim
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node Debugging and auditing
|
|
Packit Service |
4684c1 |
@subsection Debugging and auditing
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
In many cases things may not go as expected and further information,
|
|
Packit Service |
4684c1 |
to assist debugging, from @acronym{GnuTLS} is desired.
|
|
Packit Service |
4684c1 |
Those are the cases where the @funcref{gnutls_global_set_log_level} and
|
|
Packit Service |
4684c1 |
@funcref{gnutls_global_set_log_function} are to be used. Those will print
|
|
Packit Service |
4684c1 |
verbose information on the @acronym{GnuTLS} functions internal flow.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncB{gnutls_global_set_log_level,gnutls_global_set_log_function}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Alternatively the environment variable @code{GNUTLS_DEBUG_LEVEL} can be
|
|
Packit Service |
4684c1 |
set to a logging level and GnuTLS will output debugging output to standard
|
|
Packit Service |
4684c1 |
error. Other available environment variables are shown in @ref{tab:environment}.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@float Table,tab:environment
|
|
Packit Service |
4684c1 |
@multitable @columnfractions .30 .70
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@headitem Variable @tab Purpose
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item @code{GNUTLS_DEBUG_LEVEL}
|
|
Packit Service |
4684c1 |
@tab When set to a numeric value, it sets the default debugging level for GnuTLS applications.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item @code{SSLKEYLOGFILE}
|
|
Packit Service |
4684c1 |
@tab When set to a filename, GnuTLS will append to it the session keys in the NSS Key Log
|
|
Packit Service |
4684c1 |
format. That format can be read by wireshark and will allow decryption of the session for debugging.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item @code{GNUTLS_CPUID_OVERRIDE}
|
|
Packit Service |
4684c1 |
@tab That environment variable can be used to
|
|
Packit Service |
4684c1 |
explicitly enable/disable the use of certain CPU capabilities. Note that CPU
|
|
Packit Service |
4684c1 |
detection cannot be overridden, i.e., VIA options cannot be enabled on an Intel
|
|
Packit Service |
4684c1 |
CPU. The currently available options are:
|
|
Packit Service |
4684c1 |
@itemize
|
|
Packit Service |
4684c1 |
@item 0x1: Disable all run-time detected optimizations
|
|
Packit Service |
4684c1 |
@item 0x2: Enable AES-NI
|
|
Packit Service |
4684c1 |
@item 0x4: Enable SSSE3
|
|
Packit Service |
4684c1 |
@item 0x8: Enable PCLMUL
|
|
Packit Service |
4684c1 |
@item 0x10: Enable AVX
|
|
Packit Service |
4684c1 |
@item 0x20: Enable SHA_NI
|
|
Packit Service |
4684c1 |
@item 0x100000: Enable VIA padlock
|
|
Packit Service |
4684c1 |
@item 0x200000: Enable VIA PHE
|
|
Packit Service |
4684c1 |
@item 0x400000: Enable VIA PHE SHA512
|
|
Packit Service |
4684c1 |
@end itemize
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item @code{GNUTLS_FORCE_FIPS_MODE}
|
|
Packit Service |
4684c1 |
@tab In setups where GnuTLS is compiled with support for FIPS140-2 (see @ref{FIPS140-2 mode})
|
|
Packit Service |
4684c1 |
if set to one it will force the FIPS mode enablement.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@end multitable
|
|
Packit Service |
4684c1 |
@caption{Environment variables used by the library.}
|
|
Packit Service |
4684c1 |
@end float
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
When debugging is not required, important issues, such as detected
|
|
Packit Service |
4684c1 |
attacks on the protocol still need to be logged. This is provided
|
|
Packit Service |
4684c1 |
by the logging function set by
|
|
Packit Service |
4684c1 |
@funcref{gnutls_global_set_audit_log_function}. The provided function
|
|
Packit Service |
4684c1 |
will receive an message and the corresponding
|
|
Packit Service |
4684c1 |
TLS session. The session information might be used to derive IP addresses
|
|
Packit Service |
4684c1 |
or other information about the peer involved.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_global_set_audit_log_function}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node Thread safety
|
|
Packit Service |
4684c1 |
@subsection Thread safety
|
|
Packit Service |
4684c1 |
@cindex thread safety
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The @acronym{GnuTLS} library is thread safe by design, meaning that
|
|
Packit Service |
4684c1 |
objects of the library such as TLS sessions, can be safely divided across
|
|
Packit Service |
4684c1 |
threads as long as a single thread accesses a single object. This is
|
|
Packit Service |
4684c1 |
sufficient to support a server which handles several sessions per thread.
|
|
Packit Service |
4684c1 |
Read-only access to objects, for example the credentials holding structures,
|
|
Packit Service |
4684c1 |
is also thread-safe.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
A @code{gnutls_session_t} object could also be shared by two threads, one sending,
|
|
Packit Service |
4684c1 |
the other receiving. However, care must be taken on the following use cases:
|
|
Packit Service |
4684c1 |
@itemize
|
|
Packit Service |
4684c1 |
@item The re-handshake process in TLS 1.2 or earlier must be handled only in
|
|
Packit Service |
4684c1 |
a single thread and no other thread may be performing any operation.
|
|
Packit Service |
4684c1 |
@item The flag @code{GNUTLS_AUTO_REAUTH} cannot be used safely in this mode of operation.
|
|
Packit Service |
4684c1 |
@item Any other operation which may send or receive data, like key update (c.f.,
|
|
Packit Service |
4684c1 |
@funcref{gnutls_session_key_update}), must not be performed while threads
|
|
Packit Service |
4684c1 |
are receiving or writing.
|
|
Packit Service |
4684c1 |
@item The termination of a session should be handled, either by a single thread being
|
|
Packit Service |
4684c1 |
active, or by the sender thread using @funcref{gnutls_bye} with @code{GNUTLS_SHUT_WR}
|
|
Packit Service |
4684c1 |
and the receiving thread waiting for a return value of zero (or timeout on
|
|
Packit Service |
4684c1 |
certain servers which do not respond).
|
|
Packit Service |
4684c1 |
@item The functions @funcref{gnutls_transport_set_errno} and @funcref{gnutls_record_get_direction}
|
|
Packit Service |
4684c1 |
should not be relied during parallel operation.
|
|
Packit Service |
4684c1 |
@end itemize
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
For several aspects of the library (e.g., the random generator, PKCS#11
|
|
Packit Service |
4684c1 |
operations), the library may utilize mutex locks (e.g., pthreads on GNU/Linux and CriticalSection on Windows)
|
|
Packit Service |
4684c1 |
which are transparently setup on library initialization. Prior to version 3.3.0
|
|
Packit Service |
4684c1 |
these were setup by explicitly calling @funcref{gnutls_global_init}.@footnote{On special systems
|
|
Packit Service |
4684c1 |
you could manually specify the locking system using
|
|
Packit Service |
4684c1 |
the function @funcref{gnutls_global_set_mutex} before calling any other
|
|
Packit Service |
4684c1 |
GnuTLS function. Setting mutexes manually is not recommended.}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Note that, on Glibc systems, unless the application is explicitly linked
|
|
Packit Service |
4684c1 |
with the libpthread library, no mutex locks are used and setup by GnuTLS. It
|
|
Packit Service |
4684c1 |
will use the Glibc mutex stubs.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node Running in a sandbox
|
|
Packit Service |
4684c1 |
@subsection Running in a sandbox
|
|
Packit Service |
4684c1 |
@cindex seccomp
|
|
Packit Service |
4684c1 |
@cindex isolated mode
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Given that TLS protocol handling as well as X.509 certificate
|
|
Packit Service |
4684c1 |
parsing are complicated processes involving several thousands lines of code,
|
|
Packit Service |
4684c1 |
it is often desirable (and recommended) to run the TLS session handling in
|
|
Packit Service |
4684c1 |
a sandbox like seccomp. That has to be allowed by the overall software design,
|
|
Packit Service |
4684c1 |
but if available, it adds an additional layer of protection by
|
|
Packit Service |
4684c1 |
preventing parsing errors from becoming vessels for further security issues such
|
|
Packit Service |
4684c1 |
as code execution.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
GnuTLS requires the following system calls to be available for its proper
|
|
Packit Service |
4684c1 |
operation.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@itemize
|
|
Packit Service |
4684c1 |
@item nanosleep
|
|
Packit Service |
4684c1 |
@item time
|
|
Packit Service |
4684c1 |
@item gettimeofday
|
|
Packit Service |
4684c1 |
@item clock_gettime
|
|
Packit Service |
4684c1 |
@item getrusage
|
|
Packit Service |
4684c1 |
@item getpid
|
|
Packit Service |
4684c1 |
@item send
|
|
Packit Service |
4684c1 |
@item recv
|
|
Packit Service |
4684c1 |
@item sendmsg
|
|
Packit Service |
4684c1 |
@item read (to read from /dev/urandom)
|
|
Packit Service |
4684c1 |
@item getrandom (this is Linux-kernel specific)
|
|
Packit Service |
4684c1 |
@item poll
|
|
Packit Service |
4684c1 |
@end itemize
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
As well as any calls needed for memory allocation to work. Note however, that GnuTLS
|
|
Packit Service |
4684c1 |
depends on libc for the system calls, and there is no guarantee that libc will
|
|
Packit Service |
4684c1 |
call the expected system call. For that it is recommended to test your
|
|
Packit Service |
4684c1 |
program in all the targeted platforms when filters like seccomp are in place.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
An example with a seccomp filter from GnuTLS' test suite is at:
|
|
Packit Service |
4684c1 |
@url{https://gitlab.com/gnutls/gnutls/blob/master/tests/seccomp.c}.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node Sessions and fork
|
|
Packit Service |
4684c1 |
@subsection Sessions and fork
|
|
Packit Service |
4684c1 |
@cindex fork
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
A @code{gnutls_session_t} object can be shared by two processes after a fork,
|
|
Packit Service |
4684c1 |
one sending, the other receiving. In that case rehandshakes,
|
|
Packit Service |
4684c1 |
cannot and must not be performed. As with threads, the termination of a session should be
|
|
Packit Service |
4684c1 |
handled by the sender process using @funcref{gnutls_bye} with @code{GNUTLS_SHUT_WR}
|
|
Packit Service |
4684c1 |
and the receiving process waiting for a return value of zero.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node Callback functions
|
|
Packit Service |
4684c1 |
@subsection Callback functions
|
|
Packit Service |
4684c1 |
@cindex callback functions
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
There are several cases where @acronym{GnuTLS} may need out of
|
|
Packit Service |
4684c1 |
band input from your program. This is now implemented using some
|
|
Packit Service |
4684c1 |
callback functions, which your program is expected to register.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
An example of this type of functions are the push and pull callbacks
|
|
Packit Service |
4684c1 |
which are used to specify the functions that will retrieve and send
|
|
Packit Service |
4684c1 |
data to the transport layer.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncB{gnutls_transport_set_push_function,gnutls_transport_set_pull_function}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Other callback functions may require more complicated input and data
|
|
Packit Service |
4684c1 |
to be allocated. Such an example is
|
|
Packit Service |
4684c1 |
@funcref{gnutls_srp_set_server_credentials_function}.
|
|
Packit Service |
4684c1 |
All callbacks should allocate and free memory using
|
|
Packit Service |
4684c1 |
@funcintref{gnutls_malloc} and @funcintref{gnutls_free}.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node Preparation
|
|
Packit Service |
4684c1 |
@section Preparation
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
To use @acronym{GnuTLS}, you have to perform some changes to your
|
|
Packit Service |
4684c1 |
sources and your build system. The necessary changes are explained in
|
|
Packit Service |
4684c1 |
the following subsections.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@menu
|
|
Packit Service |
4684c1 |
* Headers::
|
|
Packit Service |
4684c1 |
* Initialization::
|
|
Packit Service |
4684c1 |
* Version check::
|
|
Packit Service |
4684c1 |
* Building the source::
|
|
Packit Service |
4684c1 |
@end menu
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node Headers
|
|
Packit Service |
4684c1 |
@subsection Headers
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
All the data types and functions of the @acronym{GnuTLS} library are
|
|
Packit Service |
4684c1 |
defined in the header file @file{gnutls/gnutls.h}. This must be
|
|
Packit Service |
4684c1 |
included in all programs that make use of the @acronym{GnuTLS}
|
|
Packit Service |
4684c1 |
library.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node Initialization
|
|
Packit Service |
4684c1 |
@subsection Initialization
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The GnuTLS library is initialized on load; prior to 3.3.0 was initialized by calling @funcref{gnutls_global_init}@footnote{
|
|
Packit Service |
4684c1 |
The original behavior of requiring explicit initialization can obtained by setting the
|
|
Packit Service |
4684c1 |
GNUTLS_NO_EXPLICIT_INIT environment variable to 1, or by using the macro GNUTLS_SKIP_GLOBAL_INIT
|
|
Packit Service |
4684c1 |
in a global section of your program --the latter works in systems with
|
|
Packit Service |
4684c1 |
support for weak symbols only.}. @funcref{gnutls_global_init} in
|
|
Packit Service |
4684c1 |
versions after 3.3.0 is thread-safe (see @ref{Thread safety}).
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The initialization typically enables CPU-specific acceleration, performs any required
|
|
Packit Service |
4684c1 |
precalculations needed, opens any required system devices (e.g., /dev/urandom on Linux)
|
|
Packit Service |
4684c1 |
and initializes subsystems that could be used later.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The resources allocated by the initialization process will be released
|
|
Packit Service |
4684c1 |
on library deinitialization.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Note that on certain systems file descriptors may be kept open by
|
|
Packit Service |
4684c1 |
GnuTLS (e.g. /dev/urandom) on library load. Applications closing all unknown file
|
|
Packit Service |
4684c1 |
descriptors must immediately call @funcref{gnutls_global_init}, after that, to
|
|
Packit Service |
4684c1 |
ensure they don't disrupt GnuTLS' operation.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@c In order to take advantage of the internationalization features in
|
|
Packit Service |
4684c1 |
@c GnuTLS, such as translated error messages, the application must set
|
|
Packit Service |
4684c1 |
@c the current locale using @code{setlocale} before initializing GnuTLS.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node Version check
|
|
Packit Service |
4684c1 |
@subsection Version check
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
It is often desirable to check that the version of `gnutls' used is
|
|
Packit Service |
4684c1 |
indeed one which fits all requirements. Even with binary
|
|
Packit Service |
4684c1 |
compatibility new features may have been introduced but due to problem
|
|
Packit Service |
4684c1 |
with the dynamic linker an old version is actually used. So you may
|
|
Packit Service |
4684c1 |
want to check that the version is okay right after program start-up.
|
|
Packit Service |
4684c1 |
See the function @funcref{gnutls_check_version}.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
On the other hand, it is often desirable to support more than one
|
|
Packit Service |
4684c1 |
versions of the library. In that case you could utilize compile-time
|
|
Packit Service |
4684c1 |
feature checks using the @code{GNUTLS_VERSION_NUMBER} macro.
|
|
Packit Service |
4684c1 |
For example, to conditionally add code for GnuTLS 3.2.1 or later, you may use:
|
|
Packit Service |
4684c1 |
@example
|
|
Packit Service |
4684c1 |
#if GNUTLS_VERSION_NUMBER >= 0x030201
|
|
Packit Service |
4684c1 |
...
|
|
Packit Service |
4684c1 |
#endif
|
|
Packit Service |
4684c1 |
@end example
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node Building the source
|
|
Packit Service |
4684c1 |
@subsection Building the source
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
If you want to compile a source file including the
|
|
Packit Service |
4684c1 |
@file{gnutls/gnutls.h} header file, you must make sure that the
|
|
Packit Service |
4684c1 |
compiler can find it in the directory hierarchy. This is accomplished
|
|
Packit Service |
4684c1 |
by adding the path to the directory in which the header file is
|
|
Packit Service |
4684c1 |
located to the compilers include file search path (via the @option{-I}
|
|
Packit Service |
4684c1 |
option).
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
However, the path to the include file is determined at the time the
|
|
Packit Service |
4684c1 |
source is configured. To solve this problem, the library uses the
|
|
Packit Service |
4684c1 |
external package @command{pkg-config} that knows the path to the
|
|
Packit Service |
4684c1 |
include file and other configuration options. The options that need
|
|
Packit Service |
4684c1 |
to be added to the compiler invocation at compile time are output by
|
|
Packit Service |
4684c1 |
the @option{--cflags} option to @command{pkg-config gnutls}. The
|
|
Packit Service |
4684c1 |
following example shows how it can be used at the command line:
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@example
|
|
Packit Service |
4684c1 |
gcc -c foo.c `pkg-config gnutls --cflags`
|
|
Packit Service |
4684c1 |
@end example
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Adding the output of @samp{pkg-config gnutls --cflags} to the
|
|
Packit Service |
4684c1 |
compilers command line will ensure that the compiler can find the
|
|
Packit Service |
4684c1 |
@file{gnutls/gnutls.h} header file.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
A similar problem occurs when linking the program with the library.
|
|
Packit Service |
4684c1 |
Again, the compiler has to find the library files. For this to work,
|
|
Packit Service |
4684c1 |
the path to the library files has to be added to the library search
|
|
Packit Service |
4684c1 |
path (via the @option{-L} option). For this, the option
|
|
Packit Service |
4684c1 |
@option{--libs} to @command{pkg-config gnutls} can be used. For
|
|
Packit Service |
4684c1 |
convenience, this option also outputs all other options that are
|
|
Packit Service |
4684c1 |
required to link the program with the library (for instance, the
|
|
Packit Service |
4684c1 |
@samp{-ltasn1} option). The example shows how to link @file{foo.o}
|
|
Packit Service |
4684c1 |
with the library to a program @command{foo}.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@example
|
|
Packit Service |
4684c1 |
gcc -o foo foo.o `pkg-config gnutls --libs`
|
|
Packit Service |
4684c1 |
@end example
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Of course you can also combine both examples to a single command by
|
|
Packit Service |
4684c1 |
specifying both options to @command{pkg-config}:
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@example
|
|
Packit Service |
4684c1 |
gcc -o foo foo.c `pkg-config gnutls --cflags --libs`
|
|
Packit Service |
4684c1 |
@end example
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
When a program uses the GNU autoconf system, then the following
|
|
Packit Service |
4684c1 |
line or similar can be used to detect the presence of GnuTLS.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@example
|
|
Packit Service |
4684c1 |
PKG_CHECK_MODULES([LIBGNUTLS], [gnutls >= 3.3.0])
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
AC_SUBST([LIBGNUTLS_CFLAGS])
|
|
Packit Service |
4684c1 |
AC_SUBST([LIBGNUTLS_LIBS])
|
|
Packit Service |
4684c1 |
@end example
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node Session initialization
|
|
Packit Service |
4684c1 |
@section Session initialization
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
In the previous sections we have discussed the global initialization
|
|
Packit Service |
4684c1 |
required for GnuTLS as well as the initialization required for each
|
|
Packit Service |
4684c1 |
authentication method's credentials (see @ref{Authentication}).
|
|
Packit Service |
4684c1 |
In this section we elaborate on the TLS or DTLS session initiation.
|
|
Packit Service |
4684c1 |
Each session is initialized using @funcref{gnutls_init} which among
|
|
Packit Service |
4684c1 |
others is used to specify the type of the connection (server or client),
|
|
Packit Service |
4684c1 |
and the underlying protocol type, i.e., datagram (UDP) or reliable (TCP).
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_init}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showenumdesc{gnutls_init_flags_t,The @code{gnutls_init_@-flags_t} enumeration.}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
After the session initialization details on the allowed ciphersuites
|
|
Packit Service |
4684c1 |
and protocol versions should be set using the priority functions
|
|
Packit Service |
4684c1 |
such as @funcref{gnutls_priority_set} and @funcref{gnutls_priority_set_direct}.
|
|
Packit Service |
4684c1 |
We elaborate on them in @ref{Priority Strings}.
|
|
Packit Service |
4684c1 |
The credentials used for the key exchange method, such as certificates
|
|
Packit Service |
4684c1 |
or usernames and passwords should also be associated with the session
|
|
Packit Service |
4684c1 |
current session using @funcref{gnutls_credentials_set}.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_credentials_set}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node Associating the credentials
|
|
Packit Service |
4684c1 |
@section Associating the credentials
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@menu
|
|
Packit Service |
4684c1 |
* Certificate credentials::
|
|
Packit Service |
4684c1 |
* Raw public-key credentials::
|
|
Packit Service |
4684c1 |
* SRP credentials::
|
|
Packit Service |
4684c1 |
* PSK credentials::
|
|
Packit Service |
4684c1 |
* Anonymous credentials::
|
|
Packit Service |
4684c1 |
@end menu
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Each authentication method is associated with a key exchange method, and a credentials type.
|
|
Packit Service |
4684c1 |
The contents of the credentials is method-dependent, e.g. certificates
|
|
Packit Service |
4684c1 |
for certificate authentication and should be initialized and associated
|
|
Packit Service |
4684c1 |
with a session (see @funcref{gnutls_credentials_set}). A mapping of the key exchange methods
|
|
Packit Service |
4684c1 |
with the credential types is shown in @ref{tab:key-exchange-cred}.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@float Table,tab:key-exchange-cred
|
|
Packit Service |
4684c1 |
@multitable @columnfractions .25 .25 .2 .2
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@headitem Authentication method @tab Key exchange @tab Client credentials @tab Server credentials
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item Certificate and Raw public-key
|
|
Packit Service |
4684c1 |
@tab @code{KX_RSA},
|
|
Packit Service |
4684c1 |
@code{KX_DHE_RSA},
|
|
Packit Service |
4684c1 |
@code{KX_DHE_DSS},
|
|
Packit Service |
4684c1 |
@code{KX_ECDHE_RSA},
|
|
Packit Service |
4684c1 |
@code{KX_ECDHE_ECDSA}
|
|
Packit Service |
4684c1 |
@tab @code{CRD_CERTIFICATE}
|
|
Packit Service |
4684c1 |
@tab @code{CRD_CERTIFICATE}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item Password and certificate
|
|
Packit Service |
4684c1 |
@tab @code{KX_SRP_RSA}, @code{KX_SRP_DSS}
|
|
Packit Service |
4684c1 |
@tab @code{CRD_SRP}
|
|
Packit Service |
4684c1 |
@tab @code{CRD_CERTIFICATE}, @code{CRD_SRP}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item Password
|
|
Packit Service |
4684c1 |
@tab @code{KX_SRP}
|
|
Packit Service |
4684c1 |
@tab @code{CRD_SRP}
|
|
Packit Service |
4684c1 |
@tab @code{CRD_SRP}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item Anonymous
|
|
Packit Service |
4684c1 |
@tab @code{KX_ANON_DH},
|
|
Packit Service |
4684c1 |
@code{KX_ANON_ECDH}
|
|
Packit Service |
4684c1 |
@tab @code{CRD_ANON}
|
|
Packit Service |
4684c1 |
@tab @code{CRD_ANON}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item Pre-shared key
|
|
Packit Service |
4684c1 |
@tab @code{KX_PSK},
|
|
Packit Service |
4684c1 |
@code{KX_DHE_PSK}, @code{KX_ECDHE_PSK}
|
|
Packit Service |
4684c1 |
@tab @code{CRD_PSK}
|
|
Packit Service |
4684c1 |
@tab @code{CRD_PSK}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@end multitable
|
|
Packit Service |
4684c1 |
@caption{Key exchange algorithms and the corresponding credential types.}
|
|
Packit Service |
4684c1 |
@end float
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node Certificate credentials
|
|
Packit Service |
4684c1 |
@subsection Certificates
|
|
Packit Service |
4684c1 |
@subsubheading Server certificate authentication
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
When using certificates the server is required to have at least one
|
|
Packit Service |
4684c1 |
certificate and private key pair. Clients may not hold such
|
|
Packit Service |
4684c1 |
a pair, but a server could require it. In this section we discuss
|
|
Packit Service |
4684c1 |
general issues applying to both client and server certificates. The next
|
|
Packit Service |
4684c1 |
section will elaborate on issues arising from client authentication only.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
In order to use certificate credentials one must first initialize a credentials
|
|
Packit Service |
4684c1 |
structure of type @code{gnutls_certificate_credentials_t}. After use this structure must
|
|
Packit Service |
4684c1 |
be freed. This can be done with the following functions.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncB{gnutls_certificate_allocate_credentials,gnutls_certificate_free_credentials}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
After the credentials structures are initialized, the certificate
|
|
Packit Service |
4684c1 |
and key pair must be loaded. This occurs before any @acronym{TLS}
|
|
Packit Service |
4684c1 |
session is initialized, and the same structures are reused for multiple sessions.
|
|
Packit Service |
4684c1 |
Depending on the certificate type different loading functions
|
|
Packit Service |
4684c1 |
are available, as shown below.
|
|
Packit Service |
4684c1 |
For @acronym{X.509} certificates, the functions will
|
|
Packit Service |
4684c1 |
accept and use a certificate chain that leads to a trusted
|
|
Packit Service |
4684c1 |
authority. The certificate chain must be ordered in such way that every
|
|
Packit Service |
4684c1 |
certificate certifies the one before it. The trusted authority's
|
|
Packit Service |
4684c1 |
certificate need not to be included since the peer should possess it
|
|
Packit Service |
4684c1 |
already.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncC{gnutls_certificate_set_x509_key_file2,gnutls_certificate_set_x509_key_mem2,gnutls_certificate_set_x509_key}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
It is recommended to use the higher level functions such as @funcref{gnutls_certificate_set_x509_key_file2}
|
|
Packit Service |
4684c1 |
which accept not only file names but URLs that specify objects stored in token,
|
|
Packit Service |
4684c1 |
or system certificates and keys (see @ref{Application-specific keys}). For these cases, another important
|
|
Packit Service |
4684c1 |
function is @funcref{gnutls_certificate_set_pin_function}, that
|
|
Packit Service |
4684c1 |
allows setting a callback function to retrieve a PIN if the input keys are
|
|
Packit Service |
4684c1 |
protected by PIN.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_certificate_set_pin_function}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
If the imported keys and certificates need to be accessed before any TLS session
|
|
Packit Service |
4684c1 |
is established, it is convenient to use @funcref{gnutls_certificate_set_key}
|
|
Packit Service |
4684c1 |
in combination with @funcref{gnutls_pcert_import_x509_raw} and @funcref{gnutls_privkey_import_x509_raw}.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_certificate_set_key}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
If multiple certificates are used with the functions above each
|
|
Packit Service |
4684c1 |
client's request will be served with the certificate that matches the
|
|
Packit Service |
4684c1 |
requested name (see @ref{Server name indication}).
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
As an alternative to loading from files or buffers, a callback may be used for the
|
|
Packit Service |
4684c1 |
server or the client to specify the certificate and the key at the handshake time.
|
|
Packit Service |
4684c1 |
In that case a certificate should be selected according the peer's signature
|
|
Packit Service |
4684c1 |
algorithm preferences. To get those preferences use
|
|
Packit Service |
4684c1 |
@funcref{gnutls_sign_algorithm_get_requested}. Both functions are shown below.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncD{gnutls_certificate_set_retrieve_function,gnutls_certificate_set_retrieve_function2,gnutls_certificate_set_retrieve_function3,gnutls_sign_algorithm_get_requested}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The functions above do not handle the requested server name automatically.
|
|
Packit Service |
4684c1 |
A server would need to check the name requested by the client
|
|
Packit Service |
4684c1 |
using @funcref{gnutls_server_name_get}, and serve the appropriate
|
|
Packit Service |
4684c1 |
certificate. Note that some of these functions require the @code{gnutls_pcert_st} structure to be
|
|
Packit Service |
4684c1 |
filled in. Helper functions to fill in the structure are listed below.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@verbatim
|
|
Packit Service |
4684c1 |
typedef struct gnutls_pcert_st
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
gnutls_pubkey_t pubkey;
|
|
Packit Service |
4684c1 |
gnutls_datum_t cert;
|
|
Packit Service |
4684c1 |
gnutls_certificate_type_t type;
|
|
Packit Service |
4684c1 |
} gnutls_pcert_st;
|
|
Packit Service |
4684c1 |
@end verbatim
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncC{gnutls_pcert_import_x509,gnutls_pcert_import_x509_raw,gnutls_pcert_deinit}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
In a handshake, the negotiated cipher suite depends on the
|
|
Packit Service |
4684c1 |
certificate's parameters, so some key exchange methods might not be
|
|
Packit Service |
4684c1 |
available with all certificates. @acronym{GnuTLS} will disable
|
|
Packit Service |
4684c1 |
ciphersuites that are not compatible with the key, or the enabled
|
|
Packit Service |
4684c1 |
authentication methods. For example keys marked as sign-only, will
|
|
Packit Service |
4684c1 |
not be able to access the plain RSA ciphersuites, that require
|
|
Packit Service |
4684c1 |
decryption. It is not recommended to use RSA keys for both
|
|
Packit Service |
4684c1 |
signing and encryption. If possible use a different key for the
|
|
Packit Service |
4684c1 |
@code{DHE-RSA} which uses signing and @code{RSA} that requires decryption.
|
|
Packit Service |
4684c1 |
All the key exchange methods shown in @ref{tab:key-exchange} are
|
|
Packit Service |
4684c1 |
available in certificate authentication.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@subsubheading Client certificate authentication
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
If a certificate is to be requested from the client during the handshake, the server
|
|
Packit Service |
4684c1 |
will send a certificate request message. This behavior is controlled by @funcref{gnutls_certificate_server_set_request}.
|
|
Packit Service |
4684c1 |
The request contains a list of the by the server accepted certificate signers. This list
|
|
Packit Service |
4684c1 |
is constructed using the trusted certificate authorities of the server.
|
|
Packit Service |
4684c1 |
In cases where the server supports a large number of certificate authorities
|
|
Packit Service |
4684c1 |
it makes sense not to advertise all of the names to save bandwidth. That can
|
|
Packit Service |
4684c1 |
be controlled using the function @funcref{gnutls_certificate_send_x509_rdn_sequence}.
|
|
Packit Service |
4684c1 |
This however will have the side-effect of not restricting the client to certificates
|
|
Packit Service |
4684c1 |
signed by server's acceptable signers.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_certificate_server_set_request}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_certificate_send_x509_rdn_sequence}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
On the client side, it needs to set its certificates on the credentials
|
|
Packit Service |
4684c1 |
structure, similarly to server side from a file, or via a callback. Once the
|
|
Packit Service |
4684c1 |
certificates are available in the credentials structure, the client will
|
|
Packit Service |
4684c1 |
send them if during the handshake the server requests a certificate signed
|
|
Packit Service |
4684c1 |
by the issuer of its CA.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
In the case a single certificate is available and the server does not
|
|
Packit Service |
4684c1 |
specify a signer's list, then that certificate is always sent. It is,
|
|
Packit Service |
4684c1 |
however possible, to send a certificate even when the advertised CA
|
|
Packit Service |
4684c1 |
list by the server contains CAs other than its signer. That can be achieved
|
|
Packit Service |
4684c1 |
using the @code{GNUTLS_FORCE_CLIENT_CERT} flag in @funcref{gnutls_init}.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncC{gnutls_certificate_set_x509_key_file,gnutls_certificate_set_x509_simple_pkcs12_file,gnutls_certificate_set_retrieve_function2}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@subsubheading Client or server certificate verification
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Certificate verification is possible by loading the trusted
|
|
Packit Service |
4684c1 |
authorities into the credentials structure by using
|
|
Packit Service |
4684c1 |
the following functions, applicable to X.509 certificates.
|
|
Packit Service |
4684c1 |
In modern systems it is recommended to utilize @funcref{gnutls_certificate_set_x509_system_trust}
|
|
Packit Service |
4684c1 |
which will load the trusted authorities from the system store.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_certificate_set_x509_system_trust}
|
|
Packit Service |
4684c1 |
@showfuncB{gnutls_certificate_set_x509_trust_file,gnutls_certificate_set_x509_trust_dir}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The peer's certificate will be automatically verified if
|
|
Packit Service |
4684c1 |
@funcref{gnutls_session_set_verify_cert} is called prior to handshake.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Alternatively, one must set a callback function during the handshake
|
|
Packit Service |
4684c1 |
using @funcref{gnutls_certificate_set_verify_function}, which
|
|
Packit Service |
4684c1 |
will verify the peer's certificate once received. The verification
|
|
Packit Service |
4684c1 |
should happen using @funcref{gnutls_certificate_verify_peers3} within
|
|
Packit Service |
4684c1 |
the callback. It will verify the certificate's signature and the owner
|
|
Packit Service |
4684c1 |
of the certificate. That will provide a brief verification output. If a
|
|
Packit Service |
4684c1 |
detailed output is required one should call @funcref{gnutls_certificate_get_peers}
|
|
Packit Service |
4684c1 |
to obtain the raw certificate of the peer and verify it using the
|
|
Packit Service |
4684c1 |
functions discussed in @ref{X.509 certificates}.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
In both the automatic and the manual cases, the verification status returned
|
|
Packit Service |
4684c1 |
can be printed using @funcref{gnutls_certificate_verification_status_print}.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_session_set_verify_cert}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncB{gnutls_certificate_verify_peers3,gnutls_certificate_set_verify_function}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Note that when using raw public-keys verification will not work because there is no corresponding
|
|
Packit Service |
4684c1 |
certificate body belonging to the raw key that can be verified. In that case the @funcref{gnutls_certificate_verify_peers}
|
|
Packit Service |
4684c1 |
family of functions will return a GNUTLS_E_INVALID_REQUEST error code. For authenticating raw public-keys
|
|
Packit Service |
4684c1 |
one must use an out-of-band mechanism, e.g. by comparing hashes or using trust on first use
|
|
Packit Service |
4684c1 |
(see @ref{Verifying a certificate using trust on first use authentication}).
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node Raw public-key credentials
|
|
Packit Service |
4684c1 |
@subsection Raw public-keys
|
|
Packit Service |
4684c1 |
As of version 3.6.6 GnuTLS supports @ref{Raw public-keys}. With raw public-keys only the
|
|
Packit Service |
4684c1 |
public-key part (that is normally embedded in a certificate) is transmitted to the peer.
|
|
Packit Service |
4684c1 |
In order to load a raw public-key and its corresponding private key in a credentials
|
|
Packit Service |
4684c1 |
structure one can use the following functions.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncC{gnutls_certificate_set_key,gnutls_certificate_set_rawpk_key_mem,gnutls_certificate_set_rawpk_key_file}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node SRP credentials
|
|
Packit Service |
4684c1 |
@subsection SRP
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The initialization functions in SRP credentials differ between
|
|
Packit Service |
4684c1 |
client and server.
|
|
Packit Service |
4684c1 |
Clients supporting @acronym{SRP} should set the username and password
|
|
Packit Service |
4684c1 |
prior to connection, to the credentials structure.
|
|
Packit Service |
4684c1 |
Alternatively @funcref{gnutls_srp_set_client_credentials_function}
|
|
Packit Service |
4684c1 |
may be used instead, to specify a callback function that should return the
|
|
Packit Service |
4684c1 |
SRP username and password.
|
|
Packit Service |
4684c1 |
The callback is called once during the @acronym{TLS} handshake.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncE{gnutls_srp_allocate_server_credentials,gnutls_srp_allocate_client_credentials,gnutls_srp_free_server_credentials,gnutls_srp_free_client_credentials,gnutls_srp_set_client_credentials}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_srp_set_client_credentials_function}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
In server side the default behavior of @acronym{GnuTLS} is to read
|
|
Packit Service |
4684c1 |
the usernames and @acronym{SRP} verifiers from password files. These
|
|
Packit Service |
4684c1 |
password file format is compatible the with the @emph{Stanford srp libraries}
|
|
Packit Service |
4684c1 |
format. If a different password file format is to be used, then
|
|
Packit Service |
4684c1 |
@funcref{gnutls_srp_set_server_credentials_function} should be called,
|
|
Packit Service |
4684c1 |
to set an appropriate callback.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_srp_set_server_credentials_file}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_srp_set_server_credentials_function}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node PSK credentials
|
|
Packit Service |
4684c1 |
@subsection PSK
|
|
Packit Service |
4684c1 |
The initialization functions in PSK credentials differ between
|
|
Packit Service |
4684c1 |
client and server.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncD{gnutls_psk_allocate_server_credentials,gnutls_psk_allocate_client_credentials,gnutls_psk_free_server_credentials,gnutls_psk_free_client_credentials}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Clients supporting @acronym{PSK} should supply the username and key
|
|
Packit Service |
4684c1 |
before a TLS session is established. Alternatively
|
|
Packit Service |
4684c1 |
@funcref{gnutls_psk_set_client_credentials_function} can be used to
|
|
Packit Service |
4684c1 |
specify a callback function. This has the
|
|
Packit Service |
4684c1 |
advantage that the callback will be called only if @acronym{PSK} has
|
|
Packit Service |
4684c1 |
been negotiated.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncA{gnutls_psk_set_client_credentials}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_psk_set_client_credentials_function}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
In server side the default behavior of @acronym{GnuTLS} is to read
|
|
Packit Service |
4684c1 |
the usernames and @acronym{PSK} keys from a password file. The
|
|
Packit Service |
4684c1 |
password file should contain usernames and keys in hexadecimal
|
|
Packit Service |
4684c1 |
format. The name of the password file can be stored to the credentials
|
|
Packit Service |
4684c1 |
structure by calling @funcref{gnutls_psk_set_server_credentials_file}. If
|
|
Packit Service |
4684c1 |
a different password file format is to be used, then
|
|
Packit Service |
4684c1 |
a callback should be set instead by @funcref{gnutls_psk_set_server_credentials_function}.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The server can help the client chose a suitable username and password,
|
|
Packit Service |
4684c1 |
by sending a hint. Note that there is no common profile for the PSK hint and applications
|
|
Packit Service |
4684c1 |
are discouraged to use it.
|
|
Packit Service |
4684c1 |
A server, may specify the hint by calling
|
|
Packit Service |
4684c1 |
@funcref{gnutls_psk_set_server_credentials_hint}. The client can retrieve
|
|
Packit Service |
4684c1 |
the hint, for example in the callback function, using
|
|
Packit Service |
4684c1 |
@funcref{gnutls_psk_client_get_hint}.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_psk_set_server_credentials_file}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncC{gnutls_psk_set_server_credentials_function,gnutls_psk_set_server_credentials_hint,gnutls_psk_client_get_hint}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node Anonymous credentials
|
|
Packit Service |
4684c1 |
@subsection Anonymous
|
|
Packit Service |
4684c1 |
The key exchange methods for anonymous authentication
|
|
Packit Service |
4684c1 |
since GnuTLS 3.6.0 will utilize the RFC7919 parameters, unless
|
|
Packit Service |
4684c1 |
explicit parameters have been provided and associated with an
|
|
Packit Service |
4684c1 |
anonymous credentials structure. Check @ref{Parameter generation} for more information.
|
|
Packit Service |
4684c1 |
The initialization functions for the credentials are shown below.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncD{gnutls_anon_allocate_server_credentials,gnutls_anon_allocate_client_credentials,gnutls_anon_free_server_credentials,gnutls_anon_free_client_credentials}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node Setting up the transport layer
|
|
Packit Service |
4684c1 |
@section Setting up the transport layer
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The next step is to setup the underlying transport layer details. The
|
|
Packit Service |
4684c1 |
Berkeley sockets are implicitly used by GnuTLS, thus a
|
|
Packit Service |
4684c1 |
call to @funcref{gnutls_transport_set_int} would be sufficient to
|
|
Packit Service |
4684c1 |
specify the socket descriptor.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncB{gnutls_transport_set_int,gnutls_transport_set_int2}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
If however another transport layer than TCP is selected, then
|
|
Packit Service |
4684c1 |
a pointer should be used instead to express the parameter to be
|
|
Packit Service |
4684c1 |
passed to custom functions. In that case the following functions should
|
|
Packit Service |
4684c1 |
be used instead.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncB{gnutls_transport_set_ptr,gnutls_transport_set_ptr2}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Moreover all of the following push and pull callbacks should be set.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_transport_set_push_function}
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_transport_set_vec_push_function}
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_transport_set_pull_function}
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_transport_set_pull_timeout_function}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The functions above accept a callback function which
|
|
Packit Service |
4684c1 |
should return the number of bytes written, or -1 on
|
|
Packit Service |
4684c1 |
error and should set @code{errno} appropriately.
|
|
Packit Service |
4684c1 |
In some environments, setting @code{errno} is unreliable. For example
|
|
Packit Service |
4684c1 |
Windows have several errno variables in different CRTs, or in other
|
|
Packit Service |
4684c1 |
systems it may be a non thread-local variable. If this is a concern to
|
|
Packit Service |
4684c1 |
you, call @funcref{gnutls_transport_set_errno} with the intended errno
|
|
Packit Service |
4684c1 |
value instead of setting @code{errno} directly.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_transport_set_errno}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@acronym{GnuTLS} currently only interprets the EINTR, EAGAIN and EMSGSIZE errno
|
|
Packit Service |
4684c1 |
values and returns the corresponding @acronym{GnuTLS} error codes:
|
|
Packit Service |
4684c1 |
@itemize
|
|
Packit Service |
4684c1 |
@item @code{GNUTLS_E_INTERRUPTED}
|
|
Packit Service |
4684c1 |
@item @code{GNUTLS_E_AGAIN}
|
|
Packit Service |
4684c1 |
@item @code{GNUTLS_E_LARGE_PACKET}
|
|
Packit Service |
4684c1 |
@end itemize
|
|
Packit Service |
4684c1 |
The EINTR and EAGAIN values are returned by interrupted system calls,
|
|
Packit Service |
4684c1 |
or when non blocking IO is used. All @acronym{GnuTLS} functions can be
|
|
Packit Service |
4684c1 |
resumed (called again), if any of the above error codes is returned. The
|
|
Packit Service |
4684c1 |
EMSGSIZE value is returned when attempting to send a large datagram.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
In the case of DTLS it is also desirable to override the generic
|
|
Packit Service |
4684c1 |
transport functions with functions that emulate the operation
|
|
Packit Service |
4684c1 |
of @code{recvfrom} and @code{sendto}. In addition
|
|
Packit Service |
4684c1 |
@acronym{DTLS} requires timers during the receive of a handshake
|
|
Packit Service |
4684c1 |
message, set using the @funcref{gnutls_transport_set_pull_timeout_function}
|
|
Packit Service |
4684c1 |
function. To check the retransmission timers the function
|
|
Packit Service |
4684c1 |
@funcref{gnutls_dtls_get_timeout} is provided, which returns the time
|
|
Packit Service |
4684c1 |
remaining until the next retransmission, or better the time until
|
|
Packit Service |
4684c1 |
@funcref{gnutls_handshake} should be called again.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_transport_set_pull_timeout_function}
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_dtls_get_timeout}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@menu
|
|
Packit Service |
4684c1 |
* Asynchronous operation::
|
|
Packit Service |
4684c1 |
* Reducing round-trips::
|
|
Packit Service |
4684c1 |
* Zero-roundtrip mode::
|
|
Packit Service |
4684c1 |
* Anti-replay protection::
|
|
Packit Service |
4684c1 |
* DTLS sessions::
|
|
Packit Service |
4684c1 |
* DTLS and SCTP::
|
|
Packit Service |
4684c1 |
@end menu
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node Asynchronous operation
|
|
Packit Service |
4684c1 |
@subsection Asynchronous operation
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@acronym{GnuTLS} can be used with asynchronous socket or event-driven programming.
|
|
Packit Service |
4684c1 |
The approach is similar to using Berkeley sockets under such an environment.
|
|
Packit Service |
4684c1 |
The blocking, due to network interaction, calls such as
|
|
Packit Service |
4684c1 |
@funcref{gnutls_handshake}, @funcref{gnutls_record_recv},
|
|
Packit Service |
4684c1 |
can be set to non-blocking by setting the underlying sockets to non-blocking.
|
|
Packit Service |
4684c1 |
If other push and pull functions are setup, then they should behave the same
|
|
Packit Service |
4684c1 |
way as @funcintref{recv} and @funcintref{send} when used in a non-blocking
|
|
Packit Service |
4684c1 |
way, i.e., return -1 and set errno to @code{EAGAIN}. Since, during a TLS protocol session
|
|
Packit Service |
4684c1 |
@acronym{GnuTLS} does not block except for network interaction, the non blocking
|
|
Packit Service |
4684c1 |
@code{EAGAIN} errno will be propagated and @acronym{GnuTLS} functions
|
|
Packit Service |
4684c1 |
will return the @code{GNUTLS_E_AGAIN} error code. Such calls can be resumed the
|
|
Packit Service |
4684c1 |
same way as a system call would.
|
|
Packit Service |
4684c1 |
The only exception is @funcref{gnutls_record_send},
|
|
Packit Service |
4684c1 |
which if interrupted subsequent calls need not to include the data to be
|
|
Packit Service |
4684c1 |
sent (can be called with NULL argument).
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
When using the @funcintref{poll} or @funcintref{select} system calls though, one should remember
|
|
Packit Service |
4684c1 |
that they only apply to the kernel sockets API. To check for any
|
|
Packit Service |
4684c1 |
available buffered data in a @acronym{GnuTLS} session,
|
|
Packit Service |
4684c1 |
utilize @funcref{gnutls_record_check_pending},
|
|
Packit Service |
4684c1 |
either before the @funcintref{poll} system call, or after a call to
|
|
Packit Service |
4684c1 |
@funcref{gnutls_record_recv}. Data queued by @funcref{gnutls_record_send}
|
|
Packit Service |
4684c1 |
(when interrupted) can be discarded using @funcref{gnutls_record_discard_queued}.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
An example of GnuTLS' usage with asynchronous operation can be found
|
|
Packit Service |
4684c1 |
in @code{doc/examples/tlsproxy}.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The following paragraphs describe the detailed requirements for non-blocking
|
|
Packit Service |
4684c1 |
operation when using the TLS or DTLS protocols.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@subsubsection TLS protocol
|
|
Packit Service |
4684c1 |
There are no special requirements for the TLS protocol operation in non-blocking
|
|
Packit Service |
4684c1 |
mode if a non-blocking socket is used.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
It is recommended, however, for future compatibility, when in non-blocking mode, to
|
|
Packit Service |
4684c1 |
call the @funcref{gnutls_init} function with the
|
|
Packit Service |
4684c1 |
@code{GNUTLS_NONBLOCK} flag set (see @ref{Session initialization}).
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@subsubsection Datagram TLS protocol
|
|
Packit Service |
4684c1 |
When in non-blocking mode the function, the @funcref{gnutls_init} function
|
|
Packit Service |
4684c1 |
must be called with the @code{GNUTLS_NONBLOCK} flag set (see @ref{Session initialization}).
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
In contrast with the TLS protocol, the pull timeout function is required,
|
|
Packit Service |
4684c1 |
but will only be called with a timeout of zero. In that case it should indicate
|
|
Packit Service |
4684c1 |
whether there are data to be received or not. When not using the default pull function,
|
|
Packit Service |
4684c1 |
then @funcref{gnutls_transport_set_pull_timeout_function} should be called.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Although in the TLS protocol implementation each call to receive or send
|
|
Packit Service |
4684c1 |
function implies to restoring the same function that was interrupted, in
|
|
Packit Service |
4684c1 |
the DTLS protocol this requirement isn't true.
|
|
Packit Service |
4684c1 |
There are cases where a retransmission is required, which are indicated by
|
|
Packit Service |
4684c1 |
a received message and thus @funcref{gnutls_record_get_direction} must be called
|
|
Packit Service |
4684c1 |
to decide which direction to check prior to restoring a function call.
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_record_get_direction}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
When calling @funcref{gnutls_handshake} through a multi-plexer,
|
|
Packit Service |
4684c1 |
to be able to handle properly the DTLS handshake retransmission timers,
|
|
Packit Service |
4684c1 |
the function @funcref{gnutls_dtls_get_timeout}
|
|
Packit Service |
4684c1 |
should be used to estimate when to call @funcref{gnutls_handshake} if
|
|
Packit Service |
4684c1 |
no data have been received.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node Reducing round-trips
|
|
Packit Service |
4684c1 |
@subsection Reducing round-trips
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The full TLS 1.2 handshake requires 2 round-trips to complete, and when
|
|
Packit Service |
4684c1 |
combined with TCP's SYN and SYN-ACK negotiation it extends to 3 full
|
|
Packit Service |
4684c1 |
round-trips. While, TLS 1.3 reduces that to two round-trips when under TCP,
|
|
Packit Service |
4684c1 |
it still adds considerable latency, making the protocol unsuitable for
|
|
Packit Service |
4684c1 |
certain applications.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
To optimize the handshake latency, in client side, it is possible to take
|
|
Packit Service |
4684c1 |
advantage of the TCP fast open @xcite{RFC7413} mechanism on operating
|
|
Packit Service |
4684c1 |
systems that support it. That can be done either by manually crafting the push and pull
|
|
Packit Service |
4684c1 |
callbacks, or by utilizing @funcref{gnutls_transport_set_fastopen}. In that
|
|
Packit Service |
4684c1 |
case the initial TCP handshake is eliminated, reducing the TLS 1.2 handshake round-trip
|
|
Packit Service |
4684c1 |
to 2, and the TLS 1.3 handshake to a single round-trip.
|
|
Packit Service |
4684c1 |
Note, that when this function is used, any connection failures will be reported during the
|
|
Packit Service |
4684c1 |
@funcref{gnutls_handshake} function call with error code @code{GNUTLS_E_PUSH_ERROR}.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_transport_set_fastopen}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
When restricted to TLS 1.2, and non-resumed sessions, it is possible to further
|
|
Packit Service |
4684c1 |
reduce the round-trips to a single one by taking advantage of the @ref{False Start}
|
|
Packit Service |
4684c1 |
TLS extension. This can be enabled by setting the @acronym{GNUTLS_ENABLE_FALSE_START}
|
|
Packit Service |
4684c1 |
flag on @funcref{gnutls_init}.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Under TLS 1.3, the server side can start transmitting before the handshake
|
|
Packit Service |
4684c1 |
is complete (i.e., while the client Finished message is still in flight),
|
|
Packit Service |
4684c1 |
when no client certificate authentication is requested. This, unlike false
|
|
Packit Service |
4684c1 |
start, is part of protocol design with no known security implications.
|
|
Packit Service |
4684c1 |
It can be enabled by setting the @acronym{GNUTLS_ENABLE_EARLY_START} on
|
|
Packit Service |
4684c1 |
@funcref{gnutls_init}, and the @funcref{gnutls_handshake} function will
|
|
Packit Service |
4684c1 |
return early, allowing the server to send data earlier.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node Zero-roundtrip mode
|
|
Packit Service |
4684c1 |
@subsection Zero-roundtrip mode
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Under TLS 1.3, when the client has already connected to the server and
|
|
Packit Service |
4684c1 |
is resuming a session, it can start transmitting application data during
|
|
Packit Service |
4684c1 |
handshake. This is called zero round-trip time (0-RTT) mode, and the
|
|
Packit Service |
4684c1 |
application data sent in this mode is called early data. The client can
|
|
Packit Service |
4684c1 |
send early data with @funcref{gnutls_record_send_early_data}. The
|
|
Packit Service |
4684c1 |
client should call this function before calling
|
|
Packit Service |
4684c1 |
@funcref{gnutls_handshake} and after calling
|
|
Packit Service |
4684c1 |
@funcref{gnutls_session_set_data}.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Note, however, that early data has weaker security properties than
|
|
Packit Service |
4684c1 |
normal application data sent after handshake, such as lack of forward
|
|
Packit Service |
4684c1 |
secrecy, no guarantees of non-replay between connections. Thus it is
|
|
Packit Service |
4684c1 |
disabled on the server side by default. To enable it, the server
|
|
Packit Service |
4684c1 |
needs to:
|
|
Packit Service |
4684c1 |
@enumerate
|
|
Packit Service |
4684c1 |
@item Set @acronym{GNUTLS_ENABLE_EARLY_DATA} on @funcref{gnutls_init}. Note that this option only has effect on server.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item Enable anti-replay measure. See @ref{Anti-replay protection} for the details.
|
|
Packit Service |
4684c1 |
@end enumerate
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The server caches the received early data until it is read. To set the
|
|
Packit Service |
4684c1 |
maximum amount of data to be stored in the cache, use
|
|
Packit Service |
4684c1 |
@funcref{gnutls_record_set_max_early_data_size}. After receiving the
|
|
Packit Service |
4684c1 |
EndOfEarlyData handshake message, the server can start retrieving the
|
|
Packit Service |
4684c1 |
received data with @funcref{gnutls_record_recv_early_data}. You can
|
|
Packit Service |
4684c1 |
call the function either after the handshake is complete, or through a
|
|
Packit Service |
4684c1 |
handshake hook (@funcref{gnutls_handshake_set_hook_function}).
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
When sending early data, the client should respect the maximum amount
|
|
Packit Service |
4684c1 |
of early data, which may have been previously advertised by the
|
|
Packit Service |
4684c1 |
server. It can be checked using
|
|
Packit Service |
4684c1 |
@funcref{gnutls_record_get_max_early_data_size}, right after calling
|
|
Packit Service |
4684c1 |
@funcref{gnutls_session_set_data}.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
After sending early data, to check whether the sent early data was
|
|
Packit Service |
4684c1 |
accepted by the server, use @funcref{gnutls_session_get_flags} and
|
|
Packit Service |
4684c1 |
compare the result with @acronym{GNUTLS_SFLAGS_EARLY_DATA}.
|
|
Packit Service |
4684c1 |
Similarly, on the server side, the same function and flag can be used
|
|
Packit Service |
4684c1 |
to check whether it has actually accepted early data.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node Anti-replay protection
|
|
Packit Service |
4684c1 |
@subsection Anti-replay protection
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
When 0-RTT mode is used, the server must protect itself from replay
|
|
Packit Service |
4684c1 |
attacks, where adversary client reuses duplicate session ticket to send
|
|
Packit Service |
4684c1 |
early data, before the server authenticates the client.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
GnuTLS provides a simple mechanism against replay attacks, following the
|
|
Packit Service |
4684c1 |
method called ClientHello recording. When a session ticket is accepted,
|
|
Packit Service |
4684c1 |
the server checks if the ClientHello message has been already seen. If
|
|
Packit Service |
4684c1 |
there is a duplicate, the server rejects early data.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The problem of this approach is that the number of recorded messages
|
|
Packit Service |
4684c1 |
grows indefinitely. To prevent that, the server can limit the recording
|
|
Packit Service |
4684c1 |
to a certain time window, which can be configured with
|
|
Packit Service |
4684c1 |
@funcref{gnutls_anti_replay_set_window}.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The anti-replay mechanism shall be globally initialized with
|
|
Packit Service |
4684c1 |
@funcref{gnutls_anti_replay_init}, and then attached to a session using
|
|
Packit Service |
4684c1 |
@funcref{gnutls_anti_replay_enable}. It can be deinitialized with
|
|
Packit Service |
4684c1 |
@funcref{gnutls_anti_replay_deinit}.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The server must also set up a database back-end to store ClientHello
|
|
Packit Service |
4684c1 |
messages. That can be achieved using
|
|
Packit Service |
4684c1 |
@funcref{gnutls_anti_replay_set_add_function} and
|
|
Packit Service |
4684c1 |
@funcref{gnutls_anti_replay_set_ptr}.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Note that, if the back-end stores arbitrary number of ClientHello, it
|
|
Packit Service |
4684c1 |
needs to periodically clean up the stored entries based on the time
|
|
Packit Service |
4684c1 |
window set with @funcref{gnutls_anti_replay_set_window}. The cleanup
|
|
Packit Service |
4684c1 |
can be implemented by iterating through the database entries and calling
|
|
Packit Service |
4684c1 |
@funcref{gnutls_db_check_entry_expire_time}. This is similar to session
|
|
Packit Service |
4684c1 |
database cleanup used by TLS1.2 sessions.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The full set up of the server using early data would be like the
|
|
Packit Service |
4684c1 |
following example:
|
|
Packit Service |
4684c1 |
@example
|
|
Packit Service |
4684c1 |
#define MAX_EARLY_DATA_SIZE 16384
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int
|
|
Packit Service |
4684c1 |
db_add_func(void *dbf, gnutls_datum_t key, gnutls_datum_t data)
|
|
Packit Service |
4684c1 |
@{
|
|
Packit Service |
4684c1 |
/* Return GNUTLS_E_DB_ENTRY_EXISTS, if KEY is found in the database.
|
|
Packit Service |
4684c1 |
* Otherwise, store it and return 0.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
@}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int
|
|
Packit Service |
4684c1 |
handshake_hook_func(gnutls_session_t session, unsigned int htype,
|
|
Packit Service |
4684c1 |
unsigned when, unsigned int incoming, const gnutls_datum_t *msg)
|
|
Packit Service |
4684c1 |
@{
|
|
Packit Service |
4684c1 |
int ret;
|
|
Packit Service |
4684c1 |
char buf[MAX_EARLY_DATA_SIZE];
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
assert(htype == GNUTLS_HANDSHAKE_END_OF_EARLY_DATA);
|
|
Packit Service |
4684c1 |
assert(when == GNUTLS_HOOK_POST);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (gnutls_session_get_flags(session) & GNUTLS_SFLAGS_EARLY_DATA) @{
|
|
Packit Service |
4684c1 |
ret = gnutls_record_recv_early_data(session, buf, sizeof(buf));
|
|
Packit Service |
4684c1 |
assert(ret >= 0);
|
|
Packit Service |
4684c1 |
@}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
@}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
int main()
|
|
Packit Service |
4684c1 |
@{
|
|
Packit Service |
4684c1 |
...
|
|
Packit Service |
4684c1 |
/* Initialize anti-replay measure, which can be shared
|
|
Packit Service |
4684c1 |
* among multiple sessions.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
gnutls_anti_replay_init(&anti_replay);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* Set the database back-end function for the anti-replay data. */
|
|
Packit Service |
4684c1 |
gnutls_anti_replay_set_add_function(anti_replay, db_add_func);
|
|
Packit Service |
4684c1 |
gnutls_anti_replay_set_ptr(anti_replay, NULL);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
...
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
gnutls_init(&server, GNUTLS_SERVER | GNUTLS_ENABLE_EARLY_DATA);
|
|
Packit Service |
4684c1 |
gnutls_record_set_max_early_data_size(server, MAX_EARLY_DATA_SIZE);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
...
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* Set the anti-replay measure to the session.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
gnutls_anti_replay_enable(server, anti_replay);
|
|
Packit Service |
4684c1 |
...
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* Retrieve early data in a handshake hook;
|
|
Packit Service |
4684c1 |
* you can also do that after handshake.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
gnutls_handshake_set_hook_function(server, GNUTLS_HANDSHAKE_END_OF_EARLY_DATA,
|
|
Packit Service |
4684c1 |
GNUTLS_HOOK_POST, handshake_hook_func);
|
|
Packit Service |
4684c1 |
...
|
|
Packit Service |
4684c1 |
@}
|
|
Packit Service |
4684c1 |
@end example
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node DTLS sessions
|
|
Packit Service |
4684c1 |
@subsection DTLS sessions
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Because datagram TLS can operate over connections where the client
|
|
Packit Service |
4684c1 |
cannot be reliably verified, functionality in the form of cookies, is available to prevent
|
|
Packit Service |
4684c1 |
denial of service attacks to servers. @acronym{GnuTLS} requires a server
|
|
Packit Service |
4684c1 |
to generate a secret key that is used to sign a cookie@footnote{A key of 128 bits or 16 bytes should be sufficient for this purpose.}.
|
|
Packit Service |
4684c1 |
That cookie is sent to the client using @funcref{gnutls_dtls_cookie_send}, and
|
|
Packit Service |
4684c1 |
the client must reply using the correct cookie. The server side
|
|
Packit Service |
4684c1 |
should verify the initial message sent by client using @funcref{gnutls_dtls_cookie_verify}.
|
|
Packit Service |
4684c1 |
If successful the session should be initialized and associated with
|
|
Packit Service |
4684c1 |
the cookie using @funcref{gnutls_dtls_prestate_set}, before proceeding to
|
|
Packit Service |
4684c1 |
the handshake.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncD{gnutls_key_generate,gnutls_dtls_cookie_send,gnutls_dtls_cookie_verify,gnutls_dtls_prestate_set}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Note that the above apply to server side only and they are not mandatory to be
|
|
Packit Service |
4684c1 |
used. Not using them, however, allows denial of service attacks.
|
|
Packit Service |
4684c1 |
The client side cookie handling is part of @funcref{gnutls_handshake}.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Datagrams are typically restricted by a maximum transfer unit (MTU). For that
|
|
Packit Service |
4684c1 |
both client and server side should set the correct maximum transfer unit for
|
|
Packit Service |
4684c1 |
the layer underneath @acronym{GnuTLS}. This will allow proper fragmentation
|
|
Packit Service |
4684c1 |
of DTLS messages and prevent messages from being silently discarded by the
|
|
Packit Service |
4684c1 |
transport layer. The ``correct'' maximum transfer unit can be obtained through
|
|
Packit Service |
4684c1 |
a path MTU discovery mechanism @xcite{RFC4821}.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncC{gnutls_dtls_set_mtu,gnutls_dtls_get_mtu,gnutls_dtls_get_data_mtu}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node DTLS and SCTP
|
|
Packit Service |
4684c1 |
@subsection DTLS and SCTP
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Although DTLS can run under any reliable or unreliable layer, there are
|
|
Packit Service |
4684c1 |
special requirements for SCTP according to @xcite{RFC6083}. We summarize the
|
|
Packit Service |
4684c1 |
most important below, however for a full treatment we refer to @xcite{RFC6083}.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@itemize
|
|
Packit Service |
4684c1 |
@item The MTU set via @funcref{gnutls_dtls_set_mtu} must be 2^14.
|
|
Packit Service |
4684c1 |
@item Replay detection must be disabled; use the flag @code{GNUTLS_NO_REPLAY_PROTECTION} with @funcref{gnutls_init}.
|
|
Packit Service |
4684c1 |
@item Retransmission of messages must be disabled; use @funcref{gnutls_dtls_set_timeouts}
|
|
Packit Service |
4684c1 |
with a retransmission timeout larger than the total.
|
|
Packit Service |
4684c1 |
@item Handshake, Alert and ChangeCipherSpec messages must be sent over stream 0 with unlimited reliability
|
|
Packit Service |
4684c1 |
and with the ordered delivery feature.
|
|
Packit Service |
4684c1 |
@item During a rehandshake, the caching of messages with unknown epoch is
|
|
Packit Service |
4684c1 |
not handled by GnuTLS; this must be implemented in a special pull function.
|
|
Packit Service |
4684c1 |
@end itemize
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node TLS handshake
|
|
Packit Service |
4684c1 |
@section TLS handshake
|
|
Packit Service |
4684c1 |
Once a session has been initialized and a network
|
|
Packit Service |
4684c1 |
connection has been set up, TLS and DTLS protocols
|
|
Packit Service |
4684c1 |
perform a handshake. The handshake is the actual key
|
|
Packit Service |
4684c1 |
exchange.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_handshake}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_handshake_set_timeout}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
In GnuTLS 3.5.0 and later it is recommended to use @funcref{gnutls_session_set_verify_cert}
|
|
Packit Service |
4684c1 |
for the handshake process to ensure the verification of the peer's identity.
|
|
Packit Service |
4684c1 |
That will verify the peer's certificate, against the trusted CA store while
|
|
Packit Service |
4684c1 |
accounting for stapled OCSP responses during the handshake; any error will
|
|
Packit Service |
4684c1 |
be returned as a handshake error.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
In older GnuTLS versions it is required to verify the peer's certificate
|
|
Packit Service |
4684c1 |
during the handshake by setting a callback with @funcref{gnutls_certificate_set_verify_function},
|
|
Packit Service |
4684c1 |
and then using @funcref{gnutls_certificate_verify_peers3} from it. See @ref{Certificate authentication}
|
|
Packit Service |
4684c1 |
for more information.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncB{gnutls_session_set_verify_cert,gnutls_certificate_verify_peers3}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node Data transfer and termination
|
|
Packit Service |
4684c1 |
@section Data transfer and termination
|
|
Packit Service |
4684c1 |
Once the handshake is complete and peer's identity
|
|
Packit Service |
4684c1 |
has been verified data can be exchanged. The available
|
|
Packit Service |
4684c1 |
functions resemble the POSIX @code{recv} and @code{send}
|
|
Packit Service |
4684c1 |
functions. It is suggested to use @funcref{gnutls_error_is_fatal}
|
|
Packit Service |
4684c1 |
to check whether the error codes returned by these functions are
|
|
Packit Service |
4684c1 |
fatal for the protocol or can be ignored.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_record_send}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_record_recv}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_error_is_fatal}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Although, in the TLS protocol the receive function can be called
|
|
Packit Service |
4684c1 |
at any time, when DTLS is used the GnuTLS receive functions must be
|
|
Packit Service |
4684c1 |
called once a message is available for reading, even if no data are
|
|
Packit Service |
4684c1 |
expected. This is because in DTLS various (internal) actions
|
|
Packit Service |
4684c1 |
may be required due to retransmission timers. Moreover,
|
|
Packit Service |
4684c1 |
an extended receive function is shown below, which allows the extraction
|
|
Packit Service |
4684c1 |
of the message's sequence number. Due to the unreliable nature of the
|
|
Packit Service |
4684c1 |
protocol, this field allows distinguishing out-of-order messages.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_record_recv_seq}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The @funcref{gnutls_record_check_pending} helper function is available to
|
|
Packit Service |
4684c1 |
allow checking whether data are available to be read in a @acronym{GnuTLS} session
|
|
Packit Service |
4684c1 |
buffers. Note that this function complements but does not replace @funcintref{poll},
|
|
Packit Service |
4684c1 |
i.e., @funcref{gnutls_record_check_pending} reports no data to be read, @funcintref{poll}
|
|
Packit Service |
4684c1 |
should be called to check for data in the network buffers.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_record_check_pending}
|
|
Packit Service |
4684c1 |
@showfuncA{gnutls_record_get_direction}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Once a TLS or DTLS session is no longer needed, it is
|
|
Packit Service |
4684c1 |
recommended to use @funcref{gnutls_bye} to terminate the
|
|
Packit Service |
4684c1 |
session. That way the peer is notified securely about the
|
|
Packit Service |
4684c1 |
intention of termination, which allows distinguishing it
|
|
Packit Service |
4684c1 |
from a malicious connection termination.
|
|
Packit Service |
4684c1 |
A session can be deinitialized with the @funcref{gnutls_deinit} function.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_bye}
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_deinit}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node Buffered data transfer
|
|
Packit Service |
4684c1 |
@section Buffered data transfer
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Although @funcref{gnutls_record_send} is sufficient to transmit data
|
|
Packit Service |
4684c1 |
to the peer, when many small chunks of data are to be transmitted
|
|
Packit Service |
4684c1 |
it is inefficient and wastes bandwidth due to the TLS record
|
|
Packit Service |
4684c1 |
overhead. In that case it is preferable to combine the small chunks
|
|
Packit Service |
4684c1 |
before transmission. The following functions provide that functionality.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_record_cork}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_record_uncork}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node Handling alerts
|
|
Packit Service |
4684c1 |
@section Handling alerts
|
|
Packit Service |
4684c1 |
During a TLS connection alert messages may be exchanged by the
|
|
Packit Service |
4684c1 |
two peers. Those messages may be fatal, meaning the connection
|
|
Packit Service |
4684c1 |
must be terminated afterwards, or warning when something needs
|
|
Packit Service |
4684c1 |
to be reported to the peer, but without interrupting the session.
|
|
Packit Service |
4684c1 |
The error codes @code{GNUTLS_E_@-WARNING_@-ALERT_@-RECEIVED}
|
|
Packit Service |
4684c1 |
or @code{GNUTLS_E_@-FATAL_@-ALERT_@-RECEIVED} signal those alerts
|
|
Packit Service |
4684c1 |
when received, and may be returned by all GnuTLS functions that receive
|
|
Packit Service |
4684c1 |
data from the peer, being @funcref{gnutls_handshake} and @funcref{gnutls_record_recv}.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
If those error codes are received the alert and its level should be logged
|
|
Packit Service |
4684c1 |
or reported to the peer using the functions below.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_alert_get}
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_alert_get_name}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The peer may also be warned or notified of a fatal issue
|
|
Packit Service |
4684c1 |
by using one of the functions below. All the available alerts
|
|
Packit Service |
4684c1 |
are listed in @ref{The Alert Protocol}.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_alert_send}
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_error_to_alert}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node Priority Strings
|
|
Packit Service |
4684c1 |
@section Priority strings
|
|
Packit Service |
4684c1 |
@cindex Priority strings
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@subheading How to use Priority Strings
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The GnuTLS priority strings specify the TLS session's handshake
|
|
Packit Service |
4684c1 |
algorithms and options in a compact, easy-to-use format. These
|
|
Packit Service |
4684c1 |
strings are intended as a user-specified override of the library defaults.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
That is, we recommend applications using the default settings
|
|
Packit Service |
4684c1 |
(c.f. @funcref{gnutls_set_default_priority} or
|
|
Packit Service |
4684c1 |
@funcref{gnutls_set_default_priority_append}), and provide the user
|
|
Packit Service |
4684c1 |
with access to priority strings for overriding the default behavior,
|
|
Packit Service |
4684c1 |
on configuration files, or other UI. Following such a principle,
|
|
Packit Service |
4684c1 |
makes the GnuTLS library as the default settings provider. That is
|
|
Packit Service |
4684c1 |
necessary and a good practice, because TLS protocol hardening and
|
|
Packit Service |
4684c1 |
phasing out of legacy algorithms, is easier to co-ordinate when happens
|
|
Packit Service |
4684c1 |
in a single library.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncC{gnutls_set_default_priority,gnutls_set_default_priority_append,gnutls_priority_set_direct}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The priority string translation to the internal GnuTLS form requires
|
|
Packit Service |
4684c1 |
processing and the generated internal form also occupies some memory.
|
|
Packit Service |
4684c1 |
For that, it is recommended to do that processing once in server side,
|
|
Packit Service |
4684c1 |
and share the generated data across sessions. The following functions
|
|
Packit Service |
4684c1 |
allow the generation of a "priority cache" and the sharing of it across
|
|
Packit Service |
4684c1 |
sessions.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncD{gnutls_priority_init2,gnutls_priority_init,gnutls_priority_set,gnutls_priority_deinit}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@subheading Using Priority Strings
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
A priority string string may contain a single initial keyword such as in
|
|
Packit Service |
4684c1 |
@ref{tab:prio-keywords} and may be followed by additional algorithm or
|
|
Packit Service |
4684c1 |
special keywords. Note that their description is intentionally avoiding
|
|
Packit Service |
4684c1 |
specific algorithm details, as the priority strings are not constant between
|
|
Packit Service |
4684c1 |
gnutls versions (they are periodically updated to account for cryptographic
|
|
Packit Service |
4684c1 |
advances while providing compatibility with old clients and servers).
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@float Table,tab:prio-keywords
|
|
Packit Service |
4684c1 |
@multitable @columnfractions .20 .70
|
|
Packit Service |
4684c1 |
@headitem Keyword @tab Description
|
|
Packit Service |
4684c1 |
@item @@KEYWORD @tab
|
|
Packit Service |
4684c1 |
Means that a compile-time specified system configuration file (see @ref{System-wide configuration of the library})
|
|
Packit Service |
4684c1 |
will be used to expand the provided keyword. That is used to impose system-specific policies.
|
|
Packit Service |
4684c1 |
It may be followed by additional options that will be appended to the
|
|
Packit Service |
4684c1 |
system string (e.g., "@@SYSTEM:+SRP"). The system file should have the
|
|
Packit Service |
4684c1 |
format 'KEYWORD=VALUE', e.g., 'SYSTEM=NORMAL:+ARCFOUR-128'.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Since version 3.5.1 it is allowed to specify fallback keywords such
|
|
Packit Service |
4684c1 |
as @@KEYWORD1,@@KEYWORD2, and the first valid keyword will be used.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item PERFORMANCE @tab
|
|
Packit Service |
4684c1 |
All the known to be secure ciphersuites are enabled,
|
|
Packit Service |
4684c1 |
limited to 128 bit ciphers and sorted by terms of speed
|
|
Packit Service |
4684c1 |
performance. The message authenticity security level is of 64 bits or more,
|
|
Packit Service |
4684c1 |
and the certificate verification profile is set to GNUTLS_PROFILE_LOW (80-bits).
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item NORMAL @tab
|
|
Packit Service |
4684c1 |
Means all the known to be secure ciphersuites. The ciphers are sorted by security
|
|
Packit Service |
4684c1 |
margin, although the 256-bit ciphers are included as a fallback only.
|
|
Packit Service |
4684c1 |
The message authenticity security level is of 64 bits or more,
|
|
Packit Service |
4684c1 |
and the certificate verification profile is set to GNUTLS_PROFILE_LOW (80-bits).
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
This priority string implicitly enables ECDHE and DHE. The ECDHE ciphersuites
|
|
Packit Service |
4684c1 |
are placed first in the priority order, but due to compatibility
|
|
Packit Service |
4684c1 |
issues with the DHE ciphersuites they are placed last in the priority order,
|
|
Packit Service |
4684c1 |
after the plain RSA ciphersuites.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item LEGACY @tab
|
|
Packit Service |
4684c1 |
This sets the NORMAL settings that were used for GnuTLS 3.2.x or earlier. There is
|
|
Packit Service |
4684c1 |
no verification profile set, and the allowed DH primes are considered
|
|
Packit Service |
4684c1 |
weak today (but are often used by misconfigured servers).
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item PFS @tab
|
|
Packit Service |
4684c1 |
Means all the known to be secure ciphersuites that support perfect forward
|
|
Packit Service |
4684c1 |
secrecy (ECDHE and DHE). The ciphers are sorted by security
|
|
Packit Service |
4684c1 |
margin, although the 256-bit ciphers are included as a fallback only.
|
|
Packit Service |
4684c1 |
The message authenticity security level is of 80 bits or more,
|
|
Packit Service |
4684c1 |
and the certificate verification profile is set to GNUTLS_PROFILE_LOW (80-bits).
|
|
Packit Service |
4684c1 |
This option is available since 3.2.4 or later.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item SECURE128 @tab
|
|
Packit Service |
4684c1 |
Means all known to be secure ciphersuites that offer a
|
|
Packit Service |
4684c1 |
security level 128-bit or more.
|
|
Packit Service |
4684c1 |
The message authenticity security level is of 80 bits or more,
|
|
Packit Service |
4684c1 |
and the certificate verification profile is set to GNUTLS_PROFILE_LOW (80-bits).
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item SECURE192 @tab
|
|
Packit Service |
4684c1 |
Means all the known to be secure ciphersuites that offer a
|
|
Packit Service |
4684c1 |
security level 192-bit or more.
|
|
Packit Service |
4684c1 |
The message authenticity security level is of 128 bits or more,
|
|
Packit Service |
4684c1 |
and the certificate verification profile is set to GNUTLS_PROFILE_HIGH (128-bits).
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item SECURE256 @tab
|
|
Packit Service |
4684c1 |
Currently alias for SECURE192. This option, will enable ciphers which use a
|
|
Packit Service |
4684c1 |
256-bit key but, due to limitations of the TLS protocol, the overall security
|
|
Packit Service |
4684c1 |
level will be 192-bits (the security level depends on more factors than cipher key size).
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item SUITEB128 @tab
|
|
Packit Service |
4684c1 |
Means all the NSA Suite B cryptography (RFC5430) ciphersuites
|
|
Packit Service |
4684c1 |
with an 128 bit security level, as well as the enabling of the corresponding
|
|
Packit Service |
4684c1 |
verification profile.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item SUITEB192 @tab
|
|
Packit Service |
4684c1 |
Means all the NSA Suite B cryptography (RFC5430) ciphersuites
|
|
Packit Service |
4684c1 |
with an 192 bit security level, as well as the enabling of the corresponding
|
|
Packit Service |
4684c1 |
verification profile.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item NONE @tab
|
|
Packit Service |
4684c1 |
Means nothing is enabled. This disables even protocol versions.
|
|
Packit Service |
4684c1 |
It should be followed by the algorithms to be enabled. Note that
|
|
Packit Service |
4684c1 |
using this option to build a priority string gives detailed control
|
|
Packit Service |
4684c1 |
into the resulting settings, however with new revisions of the TLS protocol
|
|
Packit Service |
4684c1 |
new priority items are routinely added, and such strings are not
|
|
Packit Service |
4684c1 |
forward compatible with new protocols. As such, we
|
|
Packit Service |
4684c1 |
advice against using that option for applications targeting multiple versions
|
|
Packit Service |
4684c1 |
of the GnuTLS library, and recommend using the defaults (see above) or
|
|
Packit Service |
4684c1 |
adjusting the defaults via @funcref{gnutls_set_default_priority_append}.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@end multitable
|
|
Packit Service |
4684c1 |
@caption{Supported initial keywords.}
|
|
Packit Service |
4684c1 |
@end float
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Unless the initial keyword is "NONE" the defaults (in preference
|
|
Packit Service |
4684c1 |
order) are for TLS protocols TLS 1.2, TLS1.1, TLS1.0;
|
|
Packit Service |
4684c1 |
for certificate types X.509.
|
|
Packit Service |
4684c1 |
In key exchange algorithms when in NORMAL or SECURE levels the
|
|
Packit Service |
4684c1 |
perfect forward secrecy algorithms take precedence of the other
|
|
Packit Service |
4684c1 |
protocols. In all cases all the supported key exchange algorithms
|
|
Packit Service |
4684c1 |
are enabled.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Note that the SECURE levels distinguish between overall security level and
|
|
Packit Service |
4684c1 |
message authenticity security level. That is because the message
|
|
Packit Service |
4684c1 |
authenticity security level requires the adversary to break
|
|
Packit Service |
4684c1 |
the algorithms at real-time during the protocol run, whilst
|
|
Packit Service |
4684c1 |
the overall security level refers to off-line adversaries
|
|
Packit Service |
4684c1 |
(e.g. adversaries breaking the ciphertext years after it was captured).
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The NONE keyword, if used, must followed by keywords specifying
|
|
Packit Service |
4684c1 |
the algorithms and protocols to be enabled. The other initial keywords
|
|
Packit Service |
4684c1 |
do not require, but may be followed by such keywords. All level keywords
|
|
Packit Service |
4684c1 |
can be combined, and for example a level of "SECURE256:+SECURE128" is
|
|
Packit Service |
4684c1 |
allowed.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The order with which every algorithm or protocol
|
|
Packit Service |
4684c1 |
is specified is significant. Algorithms specified before others
|
|
Packit Service |
4684c1 |
will take precedence. The supported in the GnuTLS version corresponding
|
|
Packit Service |
4684c1 |
to this document algorithms and protocols are shown in @ref{tab:prio-algorithms};
|
|
Packit Service |
4684c1 |
to list the supported algorithms in your currently using version use
|
|
Packit Service |
4684c1 |
@code{gnutls-cli -l}.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
To avoid collisions in order to specify a protocol version
|
|
Packit Service |
4684c1 |
with "VERS-", signature algorithms with "SIGN-" and certificate types with "CTYPE-".
|
|
Packit Service |
4684c1 |
All other algorithms don't need a prefix. Each specified keyword (except
|
|
Packit Service |
4684c1 |
for @emph{special keywords}) can be prefixed with any of the following
|
|
Packit Service |
4684c1 |
characters.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@table @asis
|
|
Packit Service |
4684c1 |
@item '!' or '-'
|
|
Packit Service |
4684c1 |
appended with an algorithm will remove this algorithm.
|
|
Packit Service |
4684c1 |
@item "+"
|
|
Packit Service |
4684c1 |
appended with an algorithm will add this algorithm.
|
|
Packit Service |
4684c1 |
@end table
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@float Table,tab:prio-algorithms
|
|
Packit Service |
4684c1 |
@multitable @columnfractions .20 .70
|
|
Packit Service |
4684c1 |
@headitem Type @tab Keywords
|
|
Packit Service |
4684c1 |
@item Ciphers @tab
|
|
Packit Service |
4684c1 |
Examples are AES-128-GCM, AES-256-GCM, AES-256-CBC, GOST28147-TC26Z-CNT; see also
|
|
Packit Service |
4684c1 |
@ref{tab:ciphers} for more options. Catch all name is CIPHER-ALL which will add
|
|
Packit Service |
4684c1 |
all the algorithms from NORMAL priority. The shortcut for secure GOST
|
|
Packit Service |
4684c1 |
algorithms is CIPHER-GOST-ALL.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item Key exchange @tab
|
|
Packit Service |
4684c1 |
RSA, DHE-RSA, DHE-DSS, SRP, SRP-RSA, SRP-DSS,
|
|
Packit Service |
4684c1 |
PSK, DHE-PSK, ECDHE-PSK, ECDHE-RSA, ECDHE-ECDSA, VKO-GOST-12, ANON-ECDH, ANON-DH.
|
|
Packit Service |
4684c1 |
Catch all name is KX-ALL which will add all the algorithms from NORMAL
|
|
Packit Service |
4684c1 |
priority. Under TLS1.3, the DHE-PSK and ECDHE-PSK strings are equivalent
|
|
Packit Service |
4684c1 |
and instruct for a Diffie-Hellman key exchange using the enabled groups. The
|
|
Packit Service |
4684c1 |
shortcut for secure GOST algorithms is KX-GOST-ALL.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item MAC @tab
|
|
Packit Service |
4684c1 |
MD5, SHA1, SHA256, SHA384, GOST28147-TC26Z-IMIT, AEAD (used with
|
|
Packit Service |
4684c1 |
GCM ciphers only). All algorithms from NORMAL priority can be accessed with
|
|
Packit Service |
4684c1 |
MAC-ALL. The shortcut for secure GOST algorithms is MAC-GOST-ALL.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item Compression algorithms @tab
|
|
Packit Service |
4684c1 |
COMP-NULL, COMP-DEFLATE. Catch all is COMP-ALL.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item TLS versions @tab
|
|
Packit Service |
4684c1 |
VERS-TLS1.0, VERS-TLS1.1, VERS-TLS1.2, VERS-TLS1.3,
|
|
Packit Service |
4684c1 |
VERS-DTLS1.0, VERS-DTLS1.2.
|
|
Packit Service |
4684c1 |
Catch all are VERS-ALL, and will enable
|
|
Packit Service |
4684c1 |
all protocols from NORMAL priority. To distinguish between TLS and DTLS
|
|
Packit Service |
4684c1 |
versions you can use VERS-TLS-ALL and VERS-DTLS-ALL.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item Signature algorithms @tab
|
|
Packit Service |
4684c1 |
SIGN-RSA-SHA1, SIGN-RSA-SHA224,
|
|
Packit Service |
4684c1 |
SIGN-RSA-SHA256, SIGN-RSA-SHA384, SIGN-RSA-SHA512, SIGN-DSA-SHA1,
|
|
Packit Service |
4684c1 |
SIGN-DSA-SHA224, SIGN-DSA-SHA256, SIGN-RSA-MD5, SIGN-ECDSA-SHA1,
|
|
Packit Service |
4684c1 |
SIGN-ECDSA-SHA224, SIGN-ECDSA-SHA256, SIGN-ECDSA-SHA384, SIGN-ECDSA-SHA512,
|
|
Packit Service |
4684c1 |
SIGN-RSA-PSS-SHA256, SIGN-RSA-PSS-SHA384, SIGN-RSA-PSS-SHA512,
|
|
Packit Service |
4684c1 |
SIGN-GOSTR341001, SIGN-GOSTR341012-256, SIGN-GOSTR341012-512.
|
|
Packit Service |
4684c1 |
Catch all which enables all algorithms from NORMAL priority is SIGN-ALL.
|
|
Packit Service |
4684c1 |
Shortcut which enables secure GOST algorithms is SIGN-GOST-ALL.
|
|
Packit Service |
4684c1 |
This option is only considered for TLS 1.2 and later.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item Groups @tab
|
|
Packit Service |
4684c1 |
GROUP-SECP256R1, GROUP-SECP384R1, GROUP-SECP521R1, GROUP-X25519, GROUP-X448,
|
|
Packit Service |
4684c1 |
GROUP-FFDHE2048, GROUP-FFDHE3072, GROUP-FFDHE4096, GROUP-FFDHE6144, and
|
|
Packit Service |
4684c1 |
GROUP-FFDHE8192.
|
|
Packit Service |
4684c1 |
Groups include both elliptic curve groups, e.g., SECP256R1, as well as
|
|
Packit Service |
4684c1 |
finite field groups such as FFDHE2048. Catch all which enables all groups
|
|
Packit Service |
4684c1 |
from NORMAL priority is GROUP-ALL. The helper keywords GROUP-DH-ALL,
|
|
Packit Service |
4684c1 |
GROUP-GOST-ALL and GROUP-EC-ALL are also available, restricting the groups
|
|
Packit Service |
4684c1 |
to finite fields (DH), GOST curves and generic elliptic curves.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item Elliptic curves (legacy) @tab
|
|
Packit Service |
4684c1 |
CURVE-SECP192R1, CURVE-SECP224R1, CURVE-SECP256R1, CURVE-SECP384R1,
|
|
Packit Service |
4684c1 |
CURVE-SECP521R1, CURVE-X25519, and CURVE-X448.
|
|
Packit Service |
4684c1 |
Catch all which enables all curves from NORMAL priority is CURVE-ALL. Note
|
|
Packit Service |
4684c1 |
that the CURVE keyword is kept for backwards compatibility only, for new
|
|
Packit Service |
4684c1 |
applications see the GROUP keyword above.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item Certificate types @tab
|
|
Packit Service |
4684c1 |
Certificate types can be given in a symmetric fashion (i.e. the same for
|
|
Packit Service |
4684c1 |
both client and server) or, as of GnuTLS 3.6.4, in an asymmetric fashion
|
|
Packit Service |
4684c1 |
(i.e. different for the client than for the server). Alternative certificate
|
|
Packit Service |
4684c1 |
types must be explicitly enabled via flags in @funcref{gnutls_init}.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The currently supported types are CTYPE-X509, CTYPE-RAWPK which apply both to
|
|
Packit Service |
4684c1 |
client and server; catch all is CTYPE-ALL. The types CTYPE-CLI-X509, CTYPE-SRV-X509,
|
|
Packit Service |
4684c1 |
CTYPE-CLI-RAWPK, CTYPE-SRV-RAWPK can be used to specialize on client or server;
|
|
Packit Service |
4684c1 |
catch all is CTYPE-CLI-ALL and CTYPE-SRV-ALL. The type 'X509' is aliased to 'X.509'
|
|
Packit Service |
4684c1 |
for legacy reasons.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item Generic @tab
|
|
Packit Service |
4684c1 |
The keyword GOST is a shortcut for secure GOST algorithms (MACs, ciphers,
|
|
Packit Service |
4684c1 |
KXes, groups and signatures). For example the following string will enable all
|
|
Packit Service |
4684c1 |
TLS 1.2 GOST ciphersuites: 'NONE:+VERS-TLS1.2:+GOST'.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@end multitable
|
|
Packit Service |
4684c1 |
@caption{The supported algorithm keywords in priority strings.}
|
|
Packit Service |
4684c1 |
@end float
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Note that the finite field groups (indicated by the FFDHE prefix) and DHE key
|
|
Packit Service |
4684c1 |
exchange methods are generally slower@footnote{It depends on the group in use. Groups with
|
|
Packit Service |
4684c1 |
less bits are always faster, but the number of bits ties with the security
|
|
Packit Service |
4684c1 |
parameter. See @ref{Selecting cryptographic key sizes}
|
|
Packit Service |
4684c1 |
for the acceptable security levels.} than their elliptic curves counterpart
|
|
Packit Service |
4684c1 |
(ECDHE).
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The available special keywords are shown in @ref{tab:prio-special1}
|
|
Packit Service |
4684c1 |
and @ref{tab:prio-special2}.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@float Table,tab:prio-special1
|
|
Packit Service |
4684c1 |
@multitable @columnfractions .45 .45
|
|
Packit Service |
4684c1 |
@headitem Keyword @tab Description
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item %COMPAT @tab
|
|
Packit Service |
4684c1 |
will enable compatibility mode. It might mean that violations
|
|
Packit Service |
4684c1 |
of the protocols are allowed as long as maximum compatibility with
|
|
Packit Service |
4684c1 |
problematic clients and servers is achieved. More specifically this
|
|
Packit Service |
4684c1 |
string will tolerate packets over the maximum allowed TLS record,
|
|
Packit Service |
4684c1 |
and add a padding to TLS Client Hello packet to prevent it being in the
|
|
Packit Service |
4684c1 |
256-512 range which is known to be causing issues with a commonly used
|
|
Packit Service |
4684c1 |
firewall (see the %DUMBFW option).
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item %DUMBFW @tab
|
|
Packit Service |
4684c1 |
will add a private extension with bogus data that make the client
|
|
Packit Service |
4684c1 |
hello exceed 512 bytes. This avoids a black hole behavior in some
|
|
Packit Service |
4684c1 |
firewalls. This is the @xcite{RFC7685} client hello padding extension, also enabled
|
|
Packit Service |
4684c1 |
with %COMPAT.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item %NO_EXTENSIONS @tab
|
|
Packit Service |
4684c1 |
will prevent the sending of any TLS extensions in client side. Note
|
|
Packit Service |
4684c1 |
that TLS 1.2 requires extensions to be used, as well as safe
|
|
Packit Service |
4684c1 |
renegotiation thus this option must be used with care. When this option
|
|
Packit Service |
4684c1 |
is set no versions later than TLS1.2 can be negotiated.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item %NO_TICKETS @tab
|
|
Packit Service |
4684c1 |
will prevent the advertizing of the TLS session ticket extension.
|
|
Packit Service |
4684c1 |
This is implied by the PFS keyword.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item %NO_SESSION_HASH @tab
|
|
Packit Service |
4684c1 |
will prevent the advertizing the TLS extended master secret (session hash)
|
|
Packit Service |
4684c1 |
extension.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item %SERVER_PRECEDENCE @tab
|
|
Packit Service |
4684c1 |
The ciphersuite will be selected according to server priorities
|
|
Packit Service |
4684c1 |
and not the client's.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item %SSL3_RECORD_VERSION @tab
|
|
Packit Service |
4684c1 |
will use SSL3.0 record version in client hello.
|
|
Packit Service |
4684c1 |
By default GnuTLS will set the minimum supported version as the
|
|
Packit Service |
4684c1 |
client hello record version (do not confuse that version with the
|
|
Packit Service |
4684c1 |
proposed handshake version at the client hello).
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item %LATEST_RECORD_VERSION @tab
|
|
Packit Service |
4684c1 |
will use the latest TLS version record version in client hello.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@end multitable
|
|
Packit Service |
4684c1 |
@caption{Special priority string keywords.}
|
|
Packit Service |
4684c1 |
@end float
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@float Table,tab:prio-special2
|
|
Packit Service |
4684c1 |
@multitable @columnfractions .45 .45
|
|
Packit Service |
4684c1 |
@headitem Keyword @tab Description
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item %STATELESS_COMPRESSION @tab
|
|
Packit Service |
4684c1 |
ignored; no longer used.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item %DISABLE_WILDCARDS @tab
|
|
Packit Service |
4684c1 |
will disable matching wildcards when comparing hostnames
|
|
Packit Service |
4684c1 |
in certificates.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item %NO_ETM @tab
|
|
Packit Service |
4684c1 |
will disable the encrypt-then-mac TLS extension (RFC7366). This is
|
|
Packit Service |
4684c1 |
implied by the %COMPAT keyword.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item %FORCE_ETM @tab
|
|
Packit Service |
4684c1 |
negotiate CBC ciphersuites only when both sides of the connection support
|
|
Packit Service |
4684c1 |
encrypt-then-mac TLS extension (RFC7366).
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item %DISABLE_SAFE_RENEGOTIATION @tab
|
|
Packit Service |
4684c1 |
will completely disable safe renegotiation
|
|
Packit Service |
4684c1 |
completely. Do not use unless you know what you are doing.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item %UNSAFE_RENEGOTIATION @tab
|
|
Packit Service |
4684c1 |
will allow handshakes and re-handshakes
|
|
Packit Service |
4684c1 |
without the safe renegotiation extension. Note that for clients
|
|
Packit Service |
4684c1 |
this mode is insecure (you may be under attack), and for servers it
|
|
Packit Service |
4684c1 |
will allow insecure clients to connect (which could be fooled by an
|
|
Packit Service |
4684c1 |
attacker). Do not use unless you know what you are doing and want
|
|
Packit Service |
4684c1 |
maximum compatibility.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item %PARTIAL_RENEGOTIATION @tab
|
|
Packit Service |
4684c1 |
will allow initial handshakes to proceed,
|
|
Packit Service |
4684c1 |
but not re-handshakes. This leaves the client vulnerable to attack,
|
|
Packit Service |
4684c1 |
and servers will be compatible with non-upgraded clients for
|
|
Packit Service |
4684c1 |
initial handshakes. This is currently the default for clients and
|
|
Packit Service |
4684c1 |
servers, for compatibility reasons.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item %SAFE_RENEGOTIATION @tab
|
|
Packit Service |
4684c1 |
will enforce safe renegotiation. Clients and
|
|
Packit Service |
4684c1 |
servers will refuse to talk to an insecure peer. Currently this
|
|
Packit Service |
4684c1 |
causes interoperability problems, but is required for full protection.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item %FALLBACK_SCSV @tab
|
|
Packit Service |
4684c1 |
will enable the use of the fallback signaling cipher suite value in the
|
|
Packit Service |
4684c1 |
client hello. Note that this should be set only by applications that
|
|
Packit Service |
4684c1 |
try to reconnect with a downgraded protocol version. See RFC7507 for
|
|
Packit Service |
4684c1 |
details.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item %VERIFY_ALLOW_BROKEN @tab
|
|
Packit Service |
4684c1 |
will allow signatures with known to be broken algorithms (such as MD5 or
|
|
Packit Service |
4684c1 |
SHA1) in certificate chains.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item %VERIFY_ALLOW_SIGN_RSA_MD5 @tab
|
|
Packit Service |
4684c1 |
will allow RSA-MD5 signatures in certificate chains.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item %VERIFY_ALLOW_SIGN_WITH_SHA1 @tab
|
|
Packit Service |
4684c1 |
will allow signatures with SHA1 hash algorithm in certificate chains.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item %VERIFY_DISABLE_CRL_CHECKS @tab
|
|
Packit Service |
4684c1 |
will disable CRL or OCSP checks in the verification of the certificate chain.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item %VERIFY_ALLOW_X509_V1_CA_CRT @tab
|
|
Packit Service |
4684c1 |
will allow V1 CAs in chains.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item %PROFILE_(LOW|LEGACY|MEDIUM|HIGH|ULTRA|FUTURE) @tab
|
|
Packit Service |
4684c1 |
require a certificate verification profile the corresponds to the specified
|
|
Packit Service |
4684c1 |
security level, see @ref{tab:key-sizes} for the mappings to values.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item %PROFILE_(SUITEB128|SUITEB192) @tab
|
|
Packit Service |
4684c1 |
require a certificate verification profile the corresponds to SUITEB. Note
|
|
Packit Service |
4684c1 |
that an initial keyword that enables SUITEB automatically sets the profile.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@end multitable
|
|
Packit Service |
4684c1 |
@caption{More priority string keywords.}
|
|
Packit Service |
4684c1 |
@end float
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Finally the ciphersuites enabled by any priority string can be
|
|
Packit Service |
4684c1 |
listed using the @code{gnutls-cli} application (see @ref{gnutls-cli Invocation}),
|
|
Packit Service |
4684c1 |
or by using the priority functions as in @ref{Listing the ciphersuites in a priority string}.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Example priority strings are:
|
|
Packit Service |
4684c1 |
@example
|
|
Packit Service |
4684c1 |
The system imposed security level:
|
|
Packit Service |
4684c1 |
"SYSTEM"
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The default priority without the HMAC-MD5:
|
|
Packit Service |
4684c1 |
"NORMAL:-MD5"
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Specifying RSA with AES-128-CBC:
|
|
Packit Service |
4684c1 |
"NONE:+VERS-TLS-ALL:+MAC-ALL:+RSA:+AES-128-CBC:+SIGN-ALL:+COMP-NULL"
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Specifying the defaults plus ARCFOUR-128:
|
|
Packit Service |
4684c1 |
"NORMAL:+ARCFOUR-128"
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Enabling the 128-bit secure ciphers, while disabling TLS 1.0:
|
|
Packit Service |
4684c1 |
"SECURE128:-VERS-TLS1.0"
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Enabling the 128-bit and 192-bit secure ciphers, while disabling all TLS versions
|
|
Packit Service |
4684c1 |
except TLS 1.2:
|
|
Packit Service |
4684c1 |
"SECURE128:+SECURE192:-VERS-ALL:+VERS-TLS1.2"
|
|
Packit Service |
4684c1 |
@end example
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node Selecting cryptographic key sizes
|
|
Packit Service |
4684c1 |
@section Selecting cryptographic key sizes
|
|
Packit Service |
4684c1 |
@cindex key sizes
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Because many algorithms are involved in TLS, it is not easy to set
|
|
Packit Service |
4684c1 |
a consistent security level. For this reason in @ref{tab:key-sizes} we
|
|
Packit Service |
4684c1 |
present some correspondence between key sizes of symmetric algorithms
|
|
Packit Service |
4684c1 |
and public key algorithms based on @xcite{ECRYPT}.
|
|
Packit Service |
4684c1 |
Those can be used to generate certificates with
|
|
Packit Service |
4684c1 |
appropriate key sizes as well as select parameters for Diffie-Hellman and SRP
|
|
Packit Service |
4684c1 |
authentication.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@float Table,tab:key-sizes
|
|
Packit Service |
4684c1 |
@multitable @columnfractions .10 .12 .10 .20 .32
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@headitem Security bits @tab RSA, DH and SRP parameter size @tab ECC key size @tab Security parameter (profile) @tab Description
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item <64
|
|
Packit Service |
4684c1 |
@tab <768
|
|
Packit Service |
4684c1 |
@tab <128
|
|
Packit Service |
4684c1 |
@tab @code{INSECURE}
|
|
Packit Service |
4684c1 |
@tab Considered to be insecure
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item 64
|
|
Packit Service |
4684c1 |
@tab 768
|
|
Packit Service |
4684c1 |
@tab 128
|
|
Packit Service |
4684c1 |
@tab @code{VERY WEAK}
|
|
Packit Service |
4684c1 |
@tab Short term protection against individuals
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item 72
|
|
Packit Service |
4684c1 |
@tab 1008
|
|
Packit Service |
4684c1 |
@tab 160
|
|
Packit Service |
4684c1 |
@tab @code{WEAK}
|
|
Packit Service |
4684c1 |
@tab Short term protection against small organizations
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item 80
|
|
Packit Service |
4684c1 |
@tab 1024
|
|
Packit Service |
4684c1 |
@tab 160
|
|
Packit Service |
4684c1 |
@tab @code{LOW}
|
|
Packit Service |
4684c1 |
@tab Very short term protection against agencies (corresponds to ENISA legacy level)
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item 96
|
|
Packit Service |
4684c1 |
@tab 1776
|
|
Packit Service |
4684c1 |
@tab 192
|
|
Packit Service |
4684c1 |
@tab @code{LEGACY}
|
|
Packit Service |
4684c1 |
@tab Legacy standard level
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item 112
|
|
Packit Service |
4684c1 |
@tab 2048
|
|
Packit Service |
4684c1 |
@tab 224
|
|
Packit Service |
4684c1 |
@tab @code{MEDIUM}
|
|
Packit Service |
4684c1 |
@tab Medium-term protection
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item 128
|
|
Packit Service |
4684c1 |
@tab 3072
|
|
Packit Service |
4684c1 |
@tab 256
|
|
Packit Service |
4684c1 |
@tab @code{HIGH}
|
|
Packit Service |
4684c1 |
@tab Long term protection (corresponds to ENISA future level)
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item 192
|
|
Packit Service |
4684c1 |
@tab 8192
|
|
Packit Service |
4684c1 |
@tab 384
|
|
Packit Service |
4684c1 |
@tab @code{ULTRA}
|
|
Packit Service |
4684c1 |
@tab Even longer term protection
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item 256
|
|
Packit Service |
4684c1 |
@tab 15424
|
|
Packit Service |
4684c1 |
@tab 512
|
|
Packit Service |
4684c1 |
@tab @code{FUTURE}
|
|
Packit Service |
4684c1 |
@tab Foreseeable future
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@end multitable
|
|
Packit Service |
4684c1 |
@caption{Key sizes and security parameters.}
|
|
Packit Service |
4684c1 |
@end float
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The first column provides a security parameter in a number of bits. This
|
|
Packit Service |
4684c1 |
gives an indication of the number of combinations to be tried by an adversary
|
|
Packit Service |
4684c1 |
to brute force a key. For example to test all possible keys in a 112 bit security parameter
|
|
Packit Service |
4684c1 |
@math{2^{112}} combinations have to be tried. For today's technology this is infeasible.
|
|
Packit Service |
4684c1 |
The next two columns correlate the security
|
|
Packit Service |
4684c1 |
parameter with actual bit sizes of parameters for DH, RSA, SRP and ECC algorithms.
|
|
Packit Service |
4684c1 |
A mapping to @code{gnutls_sec_param_t} value is given for each security parameter, on
|
|
Packit Service |
4684c1 |
the next column, and finally a brief description of the level.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@c @showenumdesc{gnutls_sec_param_t,The @code{gnutls_sec_@-param_t} enumeration.}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Note, however, that the values suggested here are nothing more than an
|
|
Packit Service |
4684c1 |
educated guess that is valid today. There are no guarantees that an
|
|
Packit Service |
4684c1 |
algorithm will remain unbreakable or that these values will remain
|
|
Packit Service |
4684c1 |
constant in time. There could be scientific breakthroughs that cannot
|
|
Packit Service |
4684c1 |
be predicted or total failure of the current public key systems by
|
|
Packit Service |
4684c1 |
quantum computers. On the other hand though the cryptosystems used in
|
|
Packit Service |
4684c1 |
TLS are selected in a conservative way and such catastrophic
|
|
Packit Service |
4684c1 |
breakthroughs or failures are believed to be unlikely.
|
|
Packit Service |
4684c1 |
The NIST publication SP 800-57 @xcite{NISTSP80057} contains a similar
|
|
Packit Service |
4684c1 |
table.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
When using @acronym{GnuTLS} and a decision on bit sizes for a public
|
|
Packit Service |
4684c1 |
key algorithm is required, use of the following functions is
|
|
Packit Service |
4684c1 |
recommended:
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_sec_param_to_pk_bits}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_pk_bits_to_sec_param}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Those functions will convert a human understandable security parameter
|
|
Packit Service |
4684c1 |
of @code{gnutls_sec_param_t} type, to a number of bits suitable for a public
|
|
Packit Service |
4684c1 |
key algorithm.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncA{gnutls_sec_param_get_name}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The following functions will set the minimum acceptable group size for Diffie-Hellman
|
|
Packit Service |
4684c1 |
and SRP authentication.
|
|
Packit Service |
4684c1 |
@showfuncB{gnutls_dh_set_prime_bits,gnutls_srp_set_prime_bits}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node Advanced topics
|
|
Packit Service |
4684c1 |
@section Advanced topics
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@menu
|
|
Packit Service |
4684c1 |
* Virtual hosts and credentials::
|
|
Packit Service |
4684c1 |
* Session resumption::
|
|
Packit Service |
4684c1 |
* Certificate verification::
|
|
Packit Service |
4684c1 |
* TLS 1.2 re-authentication::
|
|
Packit Service |
4684c1 |
* TLS 1.3 re-authentication and re-key::
|
|
Packit Service |
4684c1 |
* Parameter generation::
|
|
Packit Service |
4684c1 |
* Deriving keys for other applications/protocols::
|
|
Packit Service |
4684c1 |
* Channel Bindings::
|
|
Packit Service |
4684c1 |
* Interoperability::
|
|
Packit Service |
4684c1 |
* Compatibility with the OpenSSL library::
|
|
Packit Service |
4684c1 |
@end menu
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node Virtual hosts and credentials
|
|
Packit Service |
4684c1 |
@subsection Virtual hosts and credentials
|
|
Packit Service |
4684c1 |
@cindex virtual hosts
|
|
Packit Service |
4684c1 |
@cindex credentials
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Often when operating with virtual hosts, one may not want to associate
|
|
Packit Service |
4684c1 |
a particular certificate set to the credentials function early, before
|
|
Packit Service |
4684c1 |
the virtual host is known. That can be achieved by calling
|
|
Packit Service |
4684c1 |
@funcref{gnutls_credentials_set} within a handshake pre-hook for client
|
|
Packit Service |
4684c1 |
hello. That message contains the peer's intended hostname, and if read,
|
|
Packit Service |
4684c1 |
and the appropriate credentials are set, gnutls will be able to
|
|
Packit Service |
4684c1 |
continue in the handshake process. A brief usage example is shown
|
|
Packit Service |
4684c1 |
below.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@example
|
|
Packit Service |
4684c1 |
static int ext_hook_func(void *ctx, unsigned tls_id,
|
|
Packit Service |
4684c1 |
const unsigned char *data, unsigned size)
|
|
Packit Service |
4684c1 |
@{
|
|
Packit Service |
4684c1 |
if (tls_id == 0) @{ /* server name */
|
|
Packit Service |
4684c1 |
/* figure the advertized name - the following hack
|
|
Packit Service |
4684c1 |
* relies on the fact that this extension only supports
|
|
Packit Service |
4684c1 |
* DNS names, and due to a protocol bug cannot be extended
|
|
Packit Service |
4684c1 |
* to support anything else. */
|
|
Packit Service |
4684c1 |
if (name < 5) return 0;
|
|
Packit Service |
4684c1 |
name = data+5;
|
|
Packit Service |
4684c1 |
name_size = size-5;
|
|
Packit Service |
4684c1 |
@}
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
@}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int
|
|
Packit Service |
4684c1 |
handshake_hook_func(gnutls_session_t session, unsigned int htype,
|
|
Packit Service |
4684c1 |
unsigned when, unsigned int incoming, const gnutls_datum_t *msg)
|
|
Packit Service |
4684c1 |
@{
|
|
Packit Service |
4684c1 |
int ret;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
assert(htype == GNUTLS_HANDSHAKE_CLIENT_HELLO);
|
|
Packit Service |
4684c1 |
assert(when == GNUTLS_HOOK_PRE);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = gnutls_ext_raw_parse(NULL, ext_hook_func, msg,
|
|
Packit Service |
4684c1 |
GNUTLS_EXT_RAW_FLAG_TLS_CLIENT_HELLO);
|
|
Packit Service |
4684c1 |
assert(ret >= 0);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, cred);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
@}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
int main()
|
|
Packit Service |
4684c1 |
@{
|
|
Packit Service |
4684c1 |
...
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
gnutls_handshake_set_hook_function(server, GNUTLS_HANDSHAKE_CLIENT_HELLO,
|
|
Packit Service |
4684c1 |
GNUTLS_HOOK_PRE, handshake_hook_func);
|
|
Packit Service |
4684c1 |
...
|
|
Packit Service |
4684c1 |
@}
|
|
Packit Service |
4684c1 |
@end example
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_handshake_set_hook_function}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node Session resumption
|
|
Packit Service |
4684c1 |
@subsection Session resumption
|
|
Packit Service |
4684c1 |
@cindex resuming sessions
|
|
Packit Service |
4684c1 |
@cindex session resumption
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
To reduce time and network traffic spent in a handshake the client can
|
|
Packit Service |
4684c1 |
request session resumption from a server that previously shared a
|
|
Packit Service |
4684c1 |
session with the client.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Under TLS 1.2, in order to support resumption a server can either store
|
|
Packit Service |
4684c1 |
the session security parameters in a local database or use session
|
|
Packit Service |
4684c1 |
tickets (see @ref{Session tickets}) to delegate storage to the client.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Under TLS 1.3, session resumption is only available through session
|
|
Packit Service |
4684c1 |
tickets, and multiple tickets could be sent from server to client. That
|
|
Packit Service |
4684c1 |
provides the following advantages:
|
|
Packit Service |
4684c1 |
@itemize
|
|
Packit Service |
4684c1 |
@item When tickets are not re-used the subsequent client sessions cannot be associated with each other by an eavesdropper
|
|
Packit Service |
4684c1 |
@item On post-handshake authentication the server may send different tickets asynchronously for each identity used by client.
|
|
Packit Service |
4684c1 |
@end itemize
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@subsubheading Client side
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The client has to retrieve and store the session parameters. Before
|
|
Packit Service |
4684c1 |
establishing a new session to the same server the parameters must be
|
|
Packit Service |
4684c1 |
re-associated with the GnuTLS session using
|
|
Packit Service |
4684c1 |
@funcref{gnutls_session_set_data}.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncB{gnutls_session_get_data2,gnutls_session_set_data}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Keep in mind that sessions will be expired after some time, depending
|
|
Packit Service |
4684c1 |
on the server, and a server may choose not to resume a session
|
|
Packit Service |
4684c1 |
even when requested to. The expiration is to prevent temporal session keys
|
|
Packit Service |
4684c1 |
from becoming long-term keys. Also note that as a client you must enable,
|
|
Packit Service |
4684c1 |
using the priority functions, at least the algorithms used in the last session.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_session_is_resumed}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_session_get_id2}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@subsubheading Server side
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
A server enabling both session tickets and a storage for session data
|
|
Packit Service |
4684c1 |
would use session tickets when clients support it and the storage otherwise.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
A storing server needs to specify callback functions to store, retrieve and delete session data. These can be
|
|
Packit Service |
4684c1 |
registered with the functions below. The stored sessions in the database can be checked using @funcref{gnutls_db_check_entry}
|
|
Packit Service |
4684c1 |
for expiration.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncD{gnutls_db_set_retrieve_function,gnutls_db_set_store_function,gnutls_db_set_ptr,gnutls_db_set_remove_function}
|
|
Packit Service |
4684c1 |
@showfuncA{gnutls_db_check_entry}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
A server supporting session tickets must generate ticket encryption
|
|
Packit Service |
4684c1 |
and authentication keys using @funcref{gnutls_session_ticket_key_generate}.
|
|
Packit Service |
4684c1 |
Those keys should be associated with the GnuTLS session using
|
|
Packit Service |
4684c1 |
@funcref{gnutls_session_ticket_enable_server}.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Those will be the initial keys, but GnuTLS will rotate them regularly. The key rotation interval
|
|
Packit Service |
4684c1 |
can be changed with @funcref{gnutls_db_set_cache_expiration} and will be set to
|
|
Packit Service |
4684c1 |
three times the ticket expiration time (ie. three times the value given in that function).
|
|
Packit Service |
4684c1 |
Every such interval, new keys will be generated from those initial keys. This is a necessary mechanism
|
|
Packit Service |
4684c1 |
to prevent the keys from becoming long-term keys
|
|
Packit Service |
4684c1 |
and as such preserve forward-secrecy in the issued session tickets. If no explicit key rotation interval
|
|
Packit Service |
4684c1 |
is provided, GnuTLS will rotate them every 18 hours by default.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The master key can be shared between processes or between systems. Processes which share the same master key
|
|
Packit Service |
4684c1 |
will generate the same rotated subkeys, assuming they share the same time (irrespective of timezone differences).
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_session_ticket_enable_server}
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_session_ticket_key_generate}
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_session_resumption_requested}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The expiration time for session resumption, either in tickets or stored data
|
|
Packit Service |
4684c1 |
is set using @funcref{gnutls_db_set_cache_expiration}. This function also controls
|
|
Packit Service |
4684c1 |
the ticket key rotation period. Currently, the session key rotation interval is set
|
|
Packit Service |
4684c1 |
to 3 times the expiration time set by this function.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Under TLS 1.3, the server sends by default 2 tickets, and can send
|
|
Packit Service |
4684c1 |
additional session tickets at any time using @funcref{gnutls_session_ticket_send}.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_session_ticket_send}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node Certificate verification
|
|
Packit Service |
4684c1 |
@subsection Certificate verification
|
|
Packit Service |
4684c1 |
@cindex DANE
|
|
Packit Service |
4684c1 |
@cindex DNSSEC
|
|
Packit Service |
4684c1 |
@cindex SSH-style authentication
|
|
Packit Service |
4684c1 |
@cindex Trust on first use
|
|
Packit Service |
4684c1 |
@cindex Key pinning
|
|
Packit Service |
4684c1 |
@tindex gnutls_certificate_verify_flags
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
In this section the functionality for additional certificate verification methods is listed.
|
|
Packit Service |
4684c1 |
These methods are intended to be used in addition to normal PKI verification, in order to reduce
|
|
Packit Service |
4684c1 |
the risk of a compromised CA being undetected.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@subsubsection Trust on first use
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The GnuTLS library includes functionality to use an SSH-like trust on first use authentication.
|
|
Packit Service |
4684c1 |
The available functions to store and verify public keys are listed below.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_verify_stored_pubkey}
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_store_pubkey}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
In addition to the above the @funcref{gnutls_store_commitment} can be
|
|
Packit Service |
4684c1 |
used to implement a key-pinning architecture as in @xcite{KEYPIN}.
|
|
Packit Service |
4684c1 |
This provides a way for web server to commit on a public key that is
|
|
Packit Service |
4684c1 |
not yet active.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_store_commitment}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The storage and verification functions may be used with the default
|
|
Packit Service |
4684c1 |
text file based back-end, or another back-end may be specified. That
|
|
Packit Service |
4684c1 |
should contain storage and retrieval functions and specified as below.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncE{gnutls_tdb_init,gnutls_tdb_deinit,gnutls_tdb_set_verify_func,gnutls_tdb_set_store_func,gnutls_tdb_set_store_commitment_func}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@subsubsection DANE verification
|
|
Packit Service |
4684c1 |
Since the DANE library is not included in GnuTLS it requires programs
|
|
Packit Service |
4684c1 |
to be linked against it. This can be achieved with the following commands.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@example
|
|
Packit Service |
4684c1 |
gcc -o foo foo.c `pkg-config gnutls-dane --cflags --libs`
|
|
Packit Service |
4684c1 |
@end example
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
When a program uses the GNU autoconf system, then the following
|
|
Packit Service |
4684c1 |
line or similar can be used to detect the presence of the library.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@example
|
|
Packit Service |
4684c1 |
PKG_CHECK_MODULES([LIBDANE], [gnutls-dane >= 3.0.0])
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
AC_SUBST([LIBDANE_CFLAGS])
|
|
Packit Service |
4684c1 |
AC_SUBST([LIBDANE_LIBS])
|
|
Packit Service |
4684c1 |
@end example
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The high level functionality provided by the DANE library is shown below.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncdesc{dane_verify_crt}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncB{dane_verify_session_crt,dane_strerror}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Note that the @code{dane_state_t} structure that is accepted by both
|
|
Packit Service |
4684c1 |
verification functions is optional. It is required when many queries
|
|
Packit Service |
4684c1 |
are performed to optimize against multiple re-initializations of the
|
|
Packit Service |
4684c1 |
resolving back-end and loading of DNSSEC keys.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The following flags are returned by the verify functions to
|
|
Packit Service |
4684c1 |
indicate the status of the verification.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showenumdesc{dane_verify_status_t,The DANE verification status flags.}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
In order to generate a DANE TLSA entry to use in a DNS server
|
|
Packit Service |
4684c1 |
you may use danetool (see @ref{danetool Invocation}).
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node TLS 1.2 re-authentication
|
|
Packit Service |
4684c1 |
@subsection TLS 1.2 re-authentication
|
|
Packit Service |
4684c1 |
@cindex re-negotiation
|
|
Packit Service |
4684c1 |
@cindex re-authentication
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
In TLS 1.2 or earlier there is no distinction between re-key, re-authentication, and re-negotiation.
|
|
Packit Service |
4684c1 |
All of these use cases are handled by the TLS' rehandshake process. For that reason
|
|
Packit Service |
4684c1 |
in GnuTLS rehandshake is not transparent to the application, and the application
|
|
Packit Service |
4684c1 |
must explicitly take control of that process. In addition GnuTLS since version 3.5.0 will not
|
|
Packit Service |
4684c1 |
allow the peer to switch identities during a rehandshake.
|
|
Packit Service |
4684c1 |
The threat addressed by that behavior depends on the application protocol,
|
|
Packit Service |
4684c1 |
but primarily it protects applications from being misled
|
|
Packit Service |
4684c1 |
by a rehandshake which switches the peer's identity. Applications can
|
|
Packit Service |
4684c1 |
disable this protection by using the @code{GNUTLS_ALLOW_ID_CHANGE} flag in
|
|
Packit Service |
4684c1 |
@funcref{gnutls_init}.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The following paragraphs explain how to safely use the rehandshake process.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@subsubsection Client side
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
According to the TLS specification a client may initiate a rehandshake at any
|
|
Packit Service |
4684c1 |
time. That can be achieved by calling @funcref{gnutls_handshake} and rely on its
|
|
Packit Service |
4684c1 |
return value for the outcome of the handshake (the server may deny a rehandshake).
|
|
Packit Service |
4684c1 |
If a server requests a re-handshake, then a call to @funcref{gnutls_record_recv} will
|
|
Packit Service |
4684c1 |
return GNUTLS_E_REHANDSHAKE in the client, instructing it to call @funcref{gnutls_handshake}.
|
|
Packit Service |
4684c1 |
To deny a rehandshake request by the server it is recommended to send a warning alert
|
|
Packit Service |
4684c1 |
of type GNUTLS_A_NO_RENEGOTIATION.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Due to limitations of early protocol versions, it is required to check whether
|
|
Packit Service |
4684c1 |
safe renegotiation is in place, i.e., using @funcref{gnutls_safe_renegotiation_status},
|
|
Packit Service |
4684c1 |
which ensures that the server remains the same as the initial.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
To make re-authentication transparent to the application when requested
|
|
Packit Service |
4684c1 |
by the server, use the @code{GNUTLS_AUTO_REAUTH} flag on the
|
|
Packit Service |
4684c1 |
@funcref{gnutls_init} call. In that case the re-authentication will happen
|
|
Packit Service |
4684c1 |
in the call of @funcref{gnutls_record_recv} that received the
|
|
Packit Service |
4684c1 |
reauthentication request.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_safe_renegotiation_status}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@subsubsection Server side
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
A server which wants to instruct the client to re-authenticate, should call
|
|
Packit Service |
4684c1 |
@funcref{gnutls_rehandshake} and wait for the client to re-authenticate.
|
|
Packit Service |
4684c1 |
It is recommended to only request re-handshake when safe renegotiation is
|
|
Packit Service |
4684c1 |
enabled for that session (see @funcref{gnutls_safe_renegotiation_status} and
|
|
Packit Service |
4684c1 |
the discussion in @ref{Safe renegotiation}). A server could also encounter
|
|
Packit Service |
4684c1 |
the GNUTLS_E_REHANDSHAKE error code while receiving data. That indicates
|
|
Packit Service |
4684c1 |
a client-initiated re-handshake request. In that case the server could
|
|
Packit Service |
4684c1 |
ignore that request, perform handshake (unsafe when done generally), or
|
|
Packit Service |
4684c1 |
even drop the connection.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_rehandshake}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node TLS 1.3 re-authentication and re-key
|
|
Packit Service |
4684c1 |
@subsection TLS 1.3 re-authentication and re-key
|
|
Packit Service |
4684c1 |
@cindex re-key
|
|
Packit Service |
4684c1 |
@cindex re-negotiation
|
|
Packit Service |
4684c1 |
@cindex re-authentication
|
|
Packit Service |
4684c1 |
@cindex post-handshake authentication
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The TLS 1.3 protocol distinguishes between re-key and re-authentication.
|
|
Packit Service |
4684c1 |
The re-key process ensures that fresh keys are supplied to the already
|
|
Packit Service |
4684c1 |
negotiated parameters, and on GnuTLS can be initiated using
|
|
Packit Service |
4684c1 |
@funcref{gnutls_session_key_update}. The re-key process can be one-way
|
|
Packit Service |
4684c1 |
(i.e., the calling party only changes its keys), or two-way where the peer
|
|
Packit Service |
4684c1 |
is requested to change keys as well.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The re-authentication process, allows the connected client to switch
|
|
Packit Service |
4684c1 |
identity by presenting a new certificate. Unlike TLS 1.2, the server
|
|
Packit Service |
4684c1 |
is not allowed to change identities. That client re-authentication, or
|
|
Packit Service |
4684c1 |
post-handshake authentication can be initiated only by the server using
|
|
Packit Service |
4684c1 |
@funcref{gnutls_reauth}, and only if a client has advertized support for it.
|
|
Packit Service |
4684c1 |
Both server and client have to explicitly enable support for post handshake
|
|
Packit Service |
4684c1 |
authentication using the @code{GNUTLS_POST_HANDSHAKE_AUTH} flag at @funcref{gnutls_init}.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
A client receiving a re-authentication request will "see" the error code
|
|
Packit Service |
4684c1 |
@code{GNUTLS_E_REAUTH_REQUEST} at @funcref{gnutls_record_recv}. At this
|
|
Packit Service |
4684c1 |
point, it should also call @funcref{gnutls_reauth}.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
To make re-authentication transparent to the application when requested
|
|
Packit Service |
4684c1 |
by the server, use the @code{GNUTLS_AUTO_REAUTH} and @code{GNUTLS_POST_HANDSHAKE_AUTH}
|
|
Packit Service |
4684c1 |
flags on the @funcref{gnutls_init} call. In that case the re-authentication will happen
|
|
Packit Service |
4684c1 |
in the call of @funcref{gnutls_record_recv} that received the
|
|
Packit Service |
4684c1 |
reauthentication request.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node Parameter generation
|
|
Packit Service |
4684c1 |
@subsection Parameter generation
|
|
Packit Service |
4684c1 |
@cindex parameter generation
|
|
Packit Service |
4684c1 |
@cindex generating parameters
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Prior to GnuTLS 3.6.0 for the ephemeral or anonymous Diffie-Hellman (DH) TLS ciphersuites
|
|
Packit Service |
4684c1 |
the application was required to generate or provide
|
|
Packit Service |
4684c1 |
DH parameters. That is no longer necessary as GnuTLS utilizes DH parameters
|
|
Packit Service |
4684c1 |
and negotiation from @xcite{RFC7919}.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Applications can tune the used parameters by explicitly specifying them
|
|
Packit Service |
4684c1 |
in the priority string. In server side applications can set the
|
|
Packit Service |
4684c1 |
minimum acceptable level of DH parameters by calling
|
|
Packit Service |
4684c1 |
@funcref{gnutls_certificate_set_known_dh_params},
|
|
Packit Service |
4684c1 |
@funcref{gnutls_anon_set_server_known_dh_params}, or
|
|
Packit Service |
4684c1 |
@funcref{gnutls_psk_set_server_known_dh_params}, depending on the type
|
|
Packit Service |
4684c1 |
of the credentials, to set the lower acceptable parameter limits. Typical
|
|
Packit Service |
4684c1 |
applications should rely on the default settings.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncC{gnutls_certificate_set_known_dh_params,gnutls_anon_set_server_known_dh_params,gnutls_psk_set_server_known_dh_params}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@subsubsection Legacy parameter generation
|
|
Packit Service |
4684c1 |
Note that older than 3.5.6 versions of GnuTLS provided functions
|
|
Packit Service |
4684c1 |
to generate or import arbitrary DH parameters from a file. This
|
|
Packit Service |
4684c1 |
practice is still supported but discouraged in current versions.
|
|
Packit Service |
4684c1 |
There is no known advantage from using random parameters, while there
|
|
Packit Service |
4684c1 |
have been several occasions where applications were utilizing incorrect,
|
|
Packit Service |
4684c1 |
weak or insecure parameters. This is the main reason GnuTLS includes the
|
|
Packit Service |
4684c1 |
well-known parameters of @xcite{RFC7919} and recommends applications
|
|
Packit Service |
4684c1 |
utilizing them.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
In older applications which require to specify explicit DH parameters, we recommend
|
|
Packit Service |
4684c1 |
using @code{certtool} (of GnuTLS 3.5.6 or later) with the @code{--get-dh-params}
|
|
Packit Service |
4684c1 |
option to obtain the FFDHE parameters discussed above. The output
|
|
Packit Service |
4684c1 |
parameters of the tool are in PKCS#3 format and can be imported by
|
|
Packit Service |
4684c1 |
most existing applications.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The following functions are still supported but considered obsolete.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncC{gnutls_dh_params_generate2,gnutls_dh_params_import_pkcs3,gnutls_certificate_set_dh_params}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node Deriving keys for other applications/protocols
|
|
Packit Service |
4684c1 |
@subsection Deriving keys for other applications/protocols
|
|
Packit Service |
4684c1 |
@cindex keying material exporters
|
|
Packit Service |
4684c1 |
@cindex exporting keying material
|
|
Packit Service |
4684c1 |
@cindex deriving keys
|
|
Packit Service |
4684c1 |
@cindex key extraction
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
In several cases, after a TLS connection is established, it is desirable
|
|
Packit Service |
4684c1 |
to derive keys to be used in another application or protocol (e.g., in an
|
|
Packit Service |
4684c1 |
other TLS session using pre-shared keys). The following describe GnuTLS'
|
|
Packit Service |
4684c1 |
implementation of RFC5705 to extract keys based on a session's master secret.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The API to use is @funcref{gnutls_prf_rfc5705}. The
|
|
Packit Service |
4684c1 |
function needs to be provided with a label,
|
|
Packit Service |
4684c1 |
and additional context data to mix in the @code{context} parameter.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@showfuncdesc{gnutls_prf_rfc5705}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
For example, after establishing a TLS session using
|
|
Packit Service |
4684c1 |
@funcref{gnutls_handshake}, you can obtain 32-bytes to be used as key, using this call:
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@example
|
|
Packit Service |
4684c1 |
#define MYLABEL "EXPORTER-My-protocol-name"
|
|
Packit Service |
4684c1 |
#define MYCONTEXT "my-protocol's-1st-session"
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
char out[32];
|
|
Packit Service |
4684c1 |
rc = gnutls_prf_rfc5705 (session, sizeof(MYLABEL)-1, MYLABEL,
|
|
Packit Service |
4684c1 |
sizeof(MYCONTEXT)-1, MYCONTEXT, 32, out);
|
|
Packit Service |
4684c1 |
@end example
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The output key depends on TLS' master secret, and is the same on both client
|
|
Packit Service |
4684c1 |
and server.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
For legacy applications which need to use a more flexible API, there is
|
|
Packit Service |
4684c1 |
@funcref{gnutls_prf}, which in addition, allows to switch the mix of the
|
|
Packit Service |
4684c1 |
client and server random nonces, using the @code{server_random_first} parameter.
|
|
Packit Service |
4684c1 |
For additional flexibility and low-level access to the TLS1.2 PRF,
|
|
Packit Service |
4684c1 |
there is a low-level TLS PRF interface called @funcref{gnutls_prf_raw}.
|
|
Packit Service |
4684c1 |
That however is not functional under newer protocol versions.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node Channel Bindings
|
|
Packit Service |
4684c1 |
@subsection Channel bindings
|
|
Packit Service |
4684c1 |
@cindex channel bindings
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
In user authentication protocols (e.g., EAP or SASL mechanisms) it is
|
|
Packit Service |
4684c1 |
useful to have a unique string that identifies the secure channel that
|
|
Packit Service |
4684c1 |
is used, to bind together the user authentication with the secure
|
|
Packit Service |
4684c1 |
channel. This can protect against man-in-the-middle attacks in some
|
|
Packit Service |
4684c1 |
situations. That unique string is called a ``channel binding''. For
|
|
Packit Service |
4684c1 |
background and discussion see @xcite{RFC5056}.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
In @acronym{GnuTLS} you can extract a channel binding using the
|
|
Packit Service |
4684c1 |
@funcref{gnutls_session_channel_binding} function. Currently only the
|
|
Packit Service |
4684c1 |
type @code{GNUTLS_CB_TLS_UNIQUE} is supported, which corresponds to
|
|
Packit Service |
4684c1 |
the @code{tls-unique} channel binding for TLS defined in
|
|
Packit Service |
4684c1 |
@xcite{RFC5929}.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The following example describes how to print the channel binding data.
|
|
Packit Service |
4684c1 |
Note that it must be run after a successful TLS handshake.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@example
|
|
Packit Service |
4684c1 |
@{
|
|
Packit Service |
4684c1 |
gnutls_datum_t cb;
|
|
Packit Service |
4684c1 |
int rc;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
rc = gnutls_session_channel_binding (session,
|
|
Packit Service |
4684c1 |
GNUTLS_CB_TLS_UNIQUE,
|
|
Packit Service |
4684c1 |
&cb;;
|
|
Packit Service |
4684c1 |
if (rc)
|
|
Packit Service |
4684c1 |
fprintf (stderr, "Channel binding error: %s\n",
|
|
Packit Service |
4684c1 |
gnutls_strerror (rc));
|
|
Packit Service |
4684c1 |
else
|
|
Packit Service |
4684c1 |
@{
|
|
Packit Service |
4684c1 |
size_t i;
|
|
Packit Service |
4684c1 |
printf ("- Channel binding 'tls-unique': ");
|
|
Packit Service |
4684c1 |
for (i = 0; i < cb.size; i++)
|
|
Packit Service |
4684c1 |
printf ("%02x", cb.data[i]);
|
|
Packit Service |
4684c1 |
printf ("\n");
|
|
Packit Service |
4684c1 |
@}
|
|
Packit Service |
4684c1 |
@}
|
|
Packit Service |
4684c1 |
@end example
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node Interoperability
|
|
Packit Service |
4684c1 |
@subsection Interoperability
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The @acronym{TLS} protocols support many ciphersuites, extensions and version
|
|
Packit Service |
4684c1 |
numbers. As a result, few implementations are
|
|
Packit Service |
4684c1 |
not able to properly interoperate once faced with extensions or version protocols
|
|
Packit Service |
4684c1 |
they do not support and understand. The @acronym{TLS} protocol allows for a
|
|
Packit Service |
4684c1 |
graceful downgrade to the commonly supported options, but practice shows
|
|
Packit Service |
4684c1 |
it is not always implemented correctly.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Because there is no way to achieve maximum interoperability with broken peers
|
|
Packit Service |
4684c1 |
without sacrificing security, @acronym{GnuTLS} ignores such peers by default.
|
|
Packit Service |
4684c1 |
This might not be acceptable in cases where maximum compatibility
|
|
Packit Service |
4684c1 |
is required. Thus we allow enabling compatibility with broken peers using
|
|
Packit Service |
4684c1 |
priority strings (see @ref{Priority Strings}). A conservative priority
|
|
Packit Service |
4684c1 |
string that would disable certain @acronym{TLS} protocol
|
|
Packit Service |
4684c1 |
options that are known to cause compatibility problems, is shown below.
|
|
Packit Service |
4684c1 |
@verbatim
|
|
Packit Service |
4684c1 |
NORMAL:%COMPAT
|
|
Packit Service |
4684c1 |
@end verbatim
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
For very old broken peers that do not tolerate TLS version numbers over TLS 1.0
|
|
Packit Service |
4684c1 |
another priority string is:
|
|
Packit Service |
4684c1 |
@verbatim
|
|
Packit Service |
4684c1 |
NORMAL:-VERS-ALL:+VERS-TLS1.0:+VERS-SSL3.0:%COMPAT
|
|
Packit Service |
4684c1 |
@end verbatim
|
|
Packit Service |
4684c1 |
This priority string will in addition to above, only enable SSL 3.0 and
|
|
Packit Service |
4684c1 |
TLS 1.0 as protocols.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@node Compatibility with the OpenSSL library
|
|
Packit Service |
4684c1 |
@subsection Compatibility with the OpenSSL library
|
|
Packit Service |
4684c1 |
@cindex OpenSSL
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
To ease @acronym{GnuTLS}' integration with existing applications, a
|
|
Packit Service |
4684c1 |
compatibility layer with the OpenSSL library is included
|
|
Packit Service |
4684c1 |
in the @code{gnutls-openssl} library. This compatibility layer is not
|
|
Packit Service |
4684c1 |
complete and it is not intended to completely re-implement the OpenSSL
|
|
Packit Service |
4684c1 |
API with @acronym{GnuTLS}. It only provides limited source-level
|
|
Packit Service |
4684c1 |
compatibility.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
The prototypes for the compatibility functions are in the
|
|
Packit Service |
4684c1 |
@file{gnutls/openssl.h} header file. The limitations
|
|
Packit Service |
4684c1 |
imposed by the compatibility layer include:
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@itemize
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@item Error handling is not thread safe.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
@end itemize
|
|
Packit Service |
4684c1 |
|