Skip to content
Snippets Groups Projects
cha-gtls-app.texi 93.8 KiB
Newer Older
@node How to use GnuTLS in applications
@chapter How to use @acronym{GnuTLS} in applications

@menu
* Introduction to the library::
* Preparation::
* Session initialization::
* Associating the credentials::
* Setting up the transport layer::
* TLS handshake::
* Data transfer and termination::
* Buffered data transfer::
* Handling alerts::
* Priority Strings::
* Selecting cryptographic key sizes::
* Advanced topics::
@end menu

@node Introduction to the library
@section Introduction

This chapter tries to explain the basic functionality of the current GnuTLS
library. Note that there may be additional functionality not discussed here
but included in the library. Checking the header files in @file{/usr/include/gnutls/}
and the manpages is recommended.

@menu
* General idea::
* Error handling::
* Common types::
* Debugging and auditing::
* Thread safety::
* Running in a sandbox::
* Sessions and fork::
* Callback functions::
@end menu

@node General idea
@subsection General idea

A brief description of how @acronym{GnuTLS} sessions operate is shown
at @ref{fig-gnutls-design}. This section will become more clear when it
is completely read.
As shown in the figure, there is a read-only global state that is
initialized once by the global initialization function.  This global
structure, among others, contains the memory allocation functions
used, structures needed for the @acronym{ASN.1} parser and depending
on the system's CPU, pointers to hardware accelerated encryption functions.  This
structure is never modified by any @acronym{GnuTLS} function, except
for the deinitialization function which frees all allocated memory
and must be called after the program has permanently
finished using @acronym{GnuTLS}.

@float Figure,fig-gnutls-design
@image{gnutls-internals,12cm}
@caption{High level design of GnuTLS.}
@end float

The credentials structures are used by the authentication methods, such
as certificate authentication. They store certificates, privates keys,
and other information that is needed to prove the identity to the peer,
and/or verify the identity of the peer. The information stored in
the credentials structures is initialized once and then can be
shared by many @acronym{TLS} sessions.

A @acronym{GnuTLS} session contains all the required state and
information to handle one secure connection. The session communicates with the
peers using the provided functions of the transport layer.
Every session has a unique session ID shared with the peer.

Since TLS sessions can be resumed, servers need a
database back-end to hold the session's parameters.  Every
@acronym{GnuTLS} session after a successful handshake calls the
appropriate back-end function (see @ref{resume})
to store the newly negotiated session. The session
database is examined by the server just after having received the
client hello@footnote{The first message in a @acronym{TLS} handshake},
and if the session ID sent by the client, matches a stored session,
the stored session will be retrieved, and the new session will be a
resumed one, and will share the same session ID with the previous one.

@node Error handling
@subsection Error handling

There two types of @acronym{GnuTLS} functions. The first type returns
a boolean value, true (non-zero) or false (zero) value; these functions
are defined to return an unsigned integer type. The other type returns a
signed integer type with zero (or a positive number) indicating
success and a negative value indicating failure. For the latter
type it is recommended to check for errors as following.
@example
    ret = gnutls_function();
    if (ret < 0) @{
        return -1;
    @}
@end example
The above example checks for a failure condition rather than
for explicit success (e.g., equality to zero). That has the advantage
that future extensions of the API can be extended to provide
additional information via positive returned values (see for example
@funcref{gnutls_certificate_set_x509_key_file}).

For certain operations such as TLS handshake and TLS packet receive
there is the notion of fatal and non-fatal error codes.
Fatal errors terminate the TLS session immediately and further sends
and receives will be disallowed.  Such an example is
@code{GNUTLS_@-E_@-DECRYPTION_@-FAILED}. Non-fatal errors may warn about
something, i.e., a warning alert was received, or indicate the some
action has to be taken. This is the case with the error code
@code{GNUTLS_@-E_@-REHANDSHAKE} returned by @funcref{gnutls_record_recv}.
This error code indicates that the server requests a re-handshake. The
client may ignore this request, or may reply with an alert.  You can
test if an error code is a fatal one by using the
@funcref{gnutls_error_is_fatal}.
All errors can be converted to a descriptive string using @funcref{gnutls_strerror}.

If any non fatal errors, that require an action, are to be returned by
a function, these error codes will be documented in the function's
reference. For example the error codes @code{GNUTLS_@-E_@-WARNING_@-ALERT_@-RECEIVED} and @code{GNUTLS_@-E_@-FATAL_@-ALERT_@-RECEIVED}
that may returned when receiving data, should be handled by notifying the
user of the alert (as explained in @ref{Handling alerts}).
See @ref{Error codes}, for a description of the available error codes.

@node Common types
@subsection Common types
@cindex gnutls_datum_t
@cindex giovec_t

All strings that are to provided as input to @acronym{GnuTLS} functions
should be in UTF-8 unless otherwise specified. Output strings are also
in UTF-8 format unless otherwise specified. When functions take as input
passwords, they will normalize them using @xcite{RFC7613} rules (since
GnuTLS 3.5.7).

When data of a fixed size are provided to @acronym{GnuTLS} functions then
the helper structure @code{gnutls_datum_t} is often used. Its definition is
shown below.
@verbatim
  typedef struct
  {
    unsigned char *data;
    unsigned int size;
  } gnutls_datum_t;
@end verbatim

In functions where this structure is a returned type, if the function succeeds,
it is expected from the caller to use @code{gnutls_free()} to deinitialize the
data element after use, unless otherwise specified. If the function fails, the
contents of the @code{gnutls_datum_t} should be considered undefined and must
not be deinitialized.

Other functions that require data for scattered read use a structure similar
to @code{struct iovec} typically used by @funcintref{readv}. It is shown
below.
@verbatim
  typedef struct
  {
    void *iov_base;             /* Starting address */
    size_t iov_len;             /* Number of bytes to transfer */
  } giovec_t;
@end verbatim


@node Debugging and auditing
@subsection Debugging and auditing

In many cases things may not go as expected and further information,
to assist debugging, from @acronym{GnuTLS} is desired.
Those are the cases where the @funcref{gnutls_global_set_log_level} and
@funcref{gnutls_global_set_log_function} are to be used. Those will print
verbose information on the @acronym{GnuTLS} functions internal flow.

@showfuncB{gnutls_global_set_log_level,gnutls_global_set_log_function}

Alternatively the environment variable @code{GNUTLS_DEBUG_LEVEL} can be
set to a logging level and GnuTLS will output debugging output to standard
error. Other available environment variables are shown in @ref{tab:environment}.

@float Table,tab:environment
@multitable @columnfractions .30 .70

@headitem Variable @tab Purpose

@item @code{GNUTLS_DEBUG_LEVEL}
@tab When set to a numeric value, it sets the default debugging level for GnuTLS applications.

@item @code{SSLKEYLOGFILE}
@tab When set to a filename, GnuTLS will append to it the session keys in the NSS Key Log
format. That format can be read by wireshark and will allow decryption of the session for debugging.

@item @code{GNUTLS_CPUID_OVERRIDE}
@tab That environment variable can be used to
explicitly enable/disable the use of certain CPU capabilities. Note that CPU
detection cannot be overridden, i.e., VIA options cannot be enabled on an Intel
CPU. The currently available options are:
@itemize
@item 0x1: Disable all run-time detected optimizations
@item 0x2: Enable AES-NI
@item 0x4: Enable SSSE3
@item 0x8: Enable PCLMUL
@item 0x10: Enable AVX
@item 0x20: Enable SHA_NI
@item 0x100000: Enable VIA padlock
@item 0x200000: Enable VIA PHE
@item 0x400000: Enable VIA PHE SHA512
@end itemize

@item @code{GNUTLS_FORCE_FIPS_MODE}
@tab In setups where GnuTLS is compiled with support for FIPS140-2 (see @ref{FIPS140-2 mode})
if set to one it will force the FIPS mode enablement.

@end multitable
@caption{Environment variables used by the library.}
@end float


When debugging is not required, important issues, such as detected
attacks on the protocol still need to be logged. This is provided
by the logging function set by
@funcref{gnutls_global_set_audit_log_function}. The provided function
will receive an message and the corresponding
TLS session. The session information might be used to derive IP addresses
or other information about the peer involved.

@showfuncdesc{gnutls_global_set_audit_log_function}

@node Thread safety
@subsection Thread safety
@cindex thread safety

The @acronym{GnuTLS} library is thread safe by design, meaning that
objects of the library such as TLS sessions, can be safely divided across
threads as long as a single thread accesses a single object. This is
sufficient to support a server which handles several sessions per thread.
Read-only access to objects, for example the credentials holding structures,
is also thread-safe.

A @code{gnutls_session_t} object could also be shared by two threads, one sending,
the other receiving. However, care must be taken on the following use cases:
@itemize
@item The re-handshake process in TLS 1.2 or earlier must be handled only in
a single thread and no other thread may be performing any operation.
@item The flag @code{GNUTLS_AUTO_REAUTH} cannot be used safely in this mode of operation.
@item Any other operation which may send or receive data, like key update (c.f.,
@funcref{gnutls_session_key_update}), must not be performed while threads
are receiving or writing.
@item The termination of a session should be handled, either by a single thread being
active, or by the sender thread using @funcref{gnutls_bye} with @code{GNUTLS_SHUT_WR}
and the receiving thread waiting for a return value of zero (or timeout on
certain servers which do not respond).
@item The functions @funcref{gnutls_transport_set_errno} and @funcref{gnutls_record_get_direction}
should not be relied during parallel operation.
@end itemize

For several aspects of the library (e.g., the random generator, PKCS#11
operations), the library may utilize mutex locks (e.g., pthreads on GNU/Linux and CriticalSection on Windows)
which are transparently setup on library initialization. Prior to version 3.3.0
these were setup by explicitly calling @funcref{gnutls_global_init}.@footnote{On special systems
you could manually specify the locking system using
the function @funcref{gnutls_global_set_mutex} before calling any other
GnuTLS function. Setting mutexes manually is not recommended.}

Note that, on Glibc systems, unless the application is explicitly linked
with the libpthread library, no mutex locks are used and setup by GnuTLS. It
will use the Glibc mutex stubs.

@node Running in a sandbox
@subsection Running in a sandbox
@cindex seccomp
@cindex isolated mode

Given that TLS protocol handling as well as X.509 certificate
parsing are complicated processes involving several thousands lines of code,
it is often desirable (and recommended) to run the TLS session handling in
a sandbox like seccomp. That has to be allowed by the overall software design,
but if available, it adds an additional layer of protection by
preventing parsing errors from becoming vessels for further security issues such
as code execution.

GnuTLS requires the following system calls to be available for its proper
operation.

@itemize
@item nanosleep
@item time
@item gettimeofday
@item clock_gettime
@item getrusage
@item getpid
@item send
@item recv
@item sendmsg
@item read (to read from /dev/urandom)
@item getrandom (this is Linux-kernel specific)
@item poll
@end itemize

As well as any calls needed for memory allocation to work. Note however, that GnuTLS
depends on libc for the system calls, and there is no guarantee that libc will
call the expected system call. For that it is recommended to test your
program in all the targeted platforms when filters like seccomp are in place.

An example with a seccomp filter from GnuTLS' test suite is at:
@url{https://gitlab.com/gnutls/gnutls/blob/master/tests/seccomp.c}.

@node Sessions and fork
@subsection Sessions and fork
@cindex fork

A @code{gnutls_session_t} object can be shared by two processes after a fork,
one sending, the other receiving. In that case rehandshakes,
cannot and must not be performed. As with threads, the termination of a session should be
handled by the sender process using @funcref{gnutls_bye} with @code{GNUTLS_SHUT_WR}
and the receiving process waiting for a return value of zero.


@node Callback functions
@subsection Callback functions
@cindex callback functions

There are several cases where @acronym{GnuTLS} may need out of
band input from your program. This is now implemented using some
callback functions, which your program is expected to register.

An example of this type of functions are the push and pull callbacks
which are used to specify the functions that will retrieve and send
data to the transport layer.

@showfuncB{gnutls_transport_set_push_function,gnutls_transport_set_pull_function}

Other callback functions may require more complicated input and data
to be allocated. Such an example is
@funcref{gnutls_srp_set_server_credentials_function}.
All callbacks should allocate and free memory using
@funcintref{gnutls_malloc} and @funcintref{gnutls_free}.


@node Preparation
@section Preparation

To use @acronym{GnuTLS}, you have to perform some changes to your
sources and your build system. The necessary changes are explained in
the following subsections.

@menu
* Headers::
* Initialization::
* Version check::
* Building the source::
@end menu

@node Headers
@subsection Headers

All the data types and functions of the @acronym{GnuTLS} library are
defined in the header file @file{gnutls/gnutls.h}.  This must be
included in all programs that make use of the @acronym{GnuTLS}
library.

@node Initialization
@subsection Initialization

The GnuTLS library is initialized on load; prior to 3.3.0 was initialized by calling @funcref{gnutls_global_init}@footnote{
The original behavior of requiring explicit initialization can obtained by setting the
GNUTLS_NO_IMPLICIT_INIT environment variable to 1, or by using the macro GNUTLS_SKIP_GLOBAL_INIT
366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000
in a global section of your program --the latter works in systems with
support for weak symbols only.}. @funcref{gnutls_global_init} in
versions after 3.3.0 is thread-safe (see @ref{Thread safety}).

The initialization typically enables CPU-specific acceleration, performs any required
precalculations needed, opens any required system devices (e.g., /dev/urandom on Linux)
and initializes subsystems that could be used later.

The resources allocated by the initialization process will be released
on library deinitialization.

Note that on certain systems file descriptors may be kept open by
GnuTLS (e.g. /dev/urandom) on library load. Applications closing all unknown file
descriptors must immediately call @funcref{gnutls_global_init}, after that, to
ensure they don't disrupt GnuTLS' operation.

@c In order to take advantage of the internationalization features in
@c GnuTLS, such as translated error messages, the application must set
@c the current locale using @code{setlocale} before initializing GnuTLS.

@node Version check
@subsection Version check

It is often desirable to check that the version of `gnutls' used is
indeed one which fits all requirements.  Even with binary
compatibility new features may have been introduced but due to problem
with the dynamic linker an old version is actually used.  So you may
want to check that the version is okay right after program start-up.
See the function @funcref{gnutls_check_version}.

On the other hand, it is often desirable to support more than one
versions of the library. In that case you could utilize compile-time
feature checks using the @code{GNUTLS_VERSION_NUMBER} macro.
For example, to conditionally add code for GnuTLS 3.2.1 or later, you may use:
@example
#if GNUTLS_VERSION_NUMBER >= 0x030201
 ...
#endif
@end example

@node Building the source
@subsection Building the source

If you want to compile a source file including the
@file{gnutls/gnutls.h} header file, you must make sure that the
compiler can find it in the directory hierarchy.  This is accomplished
by adding the path to the directory in which the header file is
located to the compilers include file search path (via the @option{-I}
option).

However, the path to the include file is determined at the time the
source is configured.  To solve this problem, the library uses the
external package @command{pkg-config} that knows the path to the
include file and other configuration options.  The options that need
to be added to the compiler invocation at compile time are output by
the @option{--cflags} option to @command{pkg-config gnutls}.  The
following example shows how it can be used at the command line:

@example
gcc -c foo.c `pkg-config gnutls --cflags`
@end example

Adding the output of @samp{pkg-config gnutls --cflags} to the
compilers command line will ensure that the compiler can find the
@file{gnutls/gnutls.h} header file.

A similar problem occurs when linking the program with the library.
Again, the compiler has to find the library files.  For this to work,
the path to the library files has to be added to the library search
path (via the @option{-L} option).  For this, the option
@option{--libs} to @command{pkg-config gnutls} can be used.  For
convenience, this option also outputs all other options that are
required to link the program with the library (for instance, the
@samp{-ltasn1} option).  The example shows how to link @file{foo.o}
with the library to a program @command{foo}.

@example
gcc -o foo foo.o `pkg-config gnutls --libs`
@end example

Of course you can also combine both examples to a single command by
specifying both options to @command{pkg-config}:

@example
gcc -o foo foo.c `pkg-config gnutls --cflags --libs`
@end example

When a program uses the GNU autoconf system, then the following
line or similar can be used to detect the presence of GnuTLS.

@example
PKG_CHECK_MODULES([LIBGNUTLS], [gnutls >= 3.3.0])

AC_SUBST([LIBGNUTLS_CFLAGS])
AC_SUBST([LIBGNUTLS_LIBS])
@end example

@node Session initialization
@section Session initialization

In the previous sections we have discussed the global initialization
required for GnuTLS as well as the initialization required for each
authentication method's credentials (see @ref{Authentication}).
In this section we elaborate on the TLS or DTLS session initiation.
Each session is initialized using @funcref{gnutls_init} which among
others is used to specify the type of the connection (server or client),
and the underlying protocol type, i.e., datagram (UDP) or reliable (TCP).

@showfuncdesc{gnutls_init}

@showenumdesc{gnutls_init_flags_t,The @code{gnutls_init_@-flags_t} enumeration.}

After the session initialization details on the allowed ciphersuites
and protocol versions should be set using the priority functions
such as @funcref{gnutls_priority_set} and @funcref{gnutls_priority_set_direct}.
We elaborate on them in @ref{Priority Strings}.
The credentials used for the key exchange method, such as certificates
or usernames and passwords should also be associated with the session
current session using @funcref{gnutls_credentials_set}.

@showfuncdesc{gnutls_credentials_set}

@node Associating the credentials
@section Associating the credentials

@menu
* Certificate credentials::
* Raw public-key credentials::
* SRP credentials::
* PSK credentials::
* Anonymous credentials::
@end menu

Each authentication method is associated with a key exchange method, and a credentials type.
The contents of the credentials is method-dependent, e.g. certificates
for certificate authentication and should be initialized and associated
with a session (see @funcref{gnutls_credentials_set}).  A mapping of the key exchange methods
with the credential types is shown in @ref{tab:key-exchange-cred}.

@float Table,tab:key-exchange-cred
@multitable @columnfractions .25 .25 .2 .2

@headitem Authentication method @tab Key exchange @tab Client credentials @tab Server credentials

@item Certificate and Raw public-key
@tab @code{KX_RSA},
@code{KX_DHE_RSA},
@code{KX_DHE_DSS},
@code{KX_ECDHE_RSA},
@code{KX_ECDHE_ECDSA}
@tab @code{CRD_CERTIFICATE}
@tab @code{CRD_CERTIFICATE}

@item Password and certificate
@tab @code{KX_SRP_RSA}, @code{KX_SRP_DSS}
@tab @code{CRD_SRP}
@tab @code{CRD_CERTIFICATE}, @code{CRD_SRP}

@item Password
@tab @code{KX_SRP}
@tab @code{CRD_SRP}
@tab @code{CRD_SRP}

@item Anonymous
@tab @code{KX_ANON_DH},
@code{KX_ANON_ECDH}
@tab @code{CRD_ANON}
@tab @code{CRD_ANON}

@item Pre-shared key
@tab @code{KX_PSK},
@code{KX_DHE_PSK}, @code{KX_ECDHE_PSK}
@tab @code{CRD_PSK}
@tab @code{CRD_PSK}

@end multitable
@caption{Key exchange algorithms and the corresponding credential types.}
@end float

@node Certificate credentials
@subsection Certificates
@subsubheading Server certificate authentication

When using certificates the server is required to have at least one
certificate and private key pair. Clients may not hold such
a pair, but a server could require it. In this section we discuss
general issues applying to both client and server certificates. The next
section will elaborate on issues arising from client authentication only.

In order to use certificate credentials one must first initialize a credentials
structure of type @code{gnutls_certificate_credentials_t}. After use this structure must
be freed. This can be done with the following functions.

@showfuncB{gnutls_certificate_allocate_credentials,gnutls_certificate_free_credentials}

After the credentials structures are initialized, the certificate
and key pair must be loaded. This occurs before any @acronym{TLS}
session is initialized, and the same structures are reused for multiple sessions.
Depending on the certificate type different loading functions
are available, as shown below.
For @acronym{X.509} certificates, the functions will
accept and use a certificate chain that leads to a trusted
authority. The certificate chain must be ordered in such way that every
certificate certifies the one before it. The trusted authority's
certificate need not to be included since the peer should possess it
already.

@showfuncC{gnutls_certificate_set_x509_key_file2,gnutls_certificate_set_x509_key_mem2,gnutls_certificate_set_x509_key}

It is recommended to use the higher level functions such as @funcref{gnutls_certificate_set_x509_key_file2}
which accept not only file names but URLs that specify objects stored in token,
or system certificates and keys (see @ref{Application-specific keys}). For these cases, another important
function is @funcref{gnutls_certificate_set_pin_function}, that
allows setting a callback function to retrieve a PIN if the input keys are
protected by PIN.

@showfuncdesc{gnutls_certificate_set_pin_function}

If the imported keys and certificates need to be accessed before any TLS session
is established, it is convenient to use @funcref{gnutls_certificate_set_key}
in combination with @funcref{gnutls_pcert_import_x509_raw} and @funcref{gnutls_privkey_import_x509_raw}.

@showfuncdesc{gnutls_certificate_set_key}

If multiple certificates are used with the functions above each
client's request will be served with the certificate that matches the
requested name (see @ref{Server name indication}).

As an alternative to loading from files or buffers, a callback may be used for the
server or the client to specify the certificate and the key at the handshake time.
In that case a certificate should be selected according the peer's signature
algorithm preferences. To get those preferences use
@funcref{gnutls_sign_algorithm_get_requested}. Both functions are shown below.

@showfuncD{gnutls_certificate_set_retrieve_function,gnutls_certificate_set_retrieve_function2,gnutls_certificate_set_retrieve_function3,gnutls_sign_algorithm_get_requested}

The functions above do not handle the requested server name automatically.
A server would need to check the name requested by the client
using @funcref{gnutls_server_name_get}, and serve the appropriate
certificate. Note that some of these functions require the @code{gnutls_pcert_st} structure to be
filled in. Helper functions to fill in the structure are listed below.

@verbatim
typedef struct gnutls_pcert_st
{
  gnutls_pubkey_t pubkey;
  gnutls_datum_t cert;
  gnutls_certificate_type_t type;
} gnutls_pcert_st;
@end verbatim

@showfuncC{gnutls_pcert_import_x509,gnutls_pcert_import_x509_raw,gnutls_pcert_deinit}

In a handshake, the negotiated cipher suite depends on the
certificate's parameters, so some key exchange methods might not be
available with all certificates. @acronym{GnuTLS} will disable
ciphersuites that are not compatible with the key, or the enabled
authentication methods.  For example keys marked as sign-only, will
not be able to access the plain RSA ciphersuites, that require
decryption. It is not recommended to use RSA keys for both
signing and encryption. If possible use a different key for the
@code{DHE-RSA} which uses signing and @code{RSA} that requires decryption.
All the key exchange methods shown in @ref{tab:key-exchange} are
available in certificate authentication.


@subsubheading Client certificate authentication

If a certificate is to be requested from the client during the handshake, the server
will send a certificate request message. This behavior is controlled by @funcref{gnutls_certificate_server_set_request}.
The request contains a list of the by the server accepted certificate signers. This list
is constructed using the trusted certificate authorities of the server.
In cases where the server supports a large number of certificate authorities
it makes sense not to advertise all of the names to save bandwidth. That can
be controlled using the function @funcref{gnutls_certificate_send_x509_rdn_sequence}.
This however will have the side-effect of not restricting the client to certificates
signed by server's acceptable signers.

@showfuncdesc{gnutls_certificate_server_set_request}

@showfuncdesc{gnutls_certificate_send_x509_rdn_sequence}

On the client side, it needs to set its certificates on the credentials
structure, similarly to server side from a file, or via a callback. Once the
certificates are available in the credentials structure, the client will
send them if during the handshake the server requests a certificate signed
by the issuer of its CA.

In the case a single certificate is available and the server does not
specify a signer's list, then that certificate is always sent. It is,
however possible, to send a certificate even when the advertised CA
list by the server contains CAs other than its signer. That can be achieved
using the @code{GNUTLS_FORCE_CLIENT_CERT} flag in @funcref{gnutls_init}.

@showfuncC{gnutls_certificate_set_x509_key_file,gnutls_certificate_set_x509_simple_pkcs12_file,gnutls_certificate_set_retrieve_function2}


@subsubheading Client or server certificate verification

Certificate verification is possible by loading the trusted
authorities into the credentials structure by using
the following functions, applicable to X.509 certificates.
In modern systems it is recommended to utilize @funcref{gnutls_certificate_set_x509_system_trust}
which will load the trusted authorities from the system store.

@showfuncdesc{gnutls_certificate_set_x509_system_trust}
@showfuncB{gnutls_certificate_set_x509_trust_file,gnutls_certificate_set_x509_trust_dir}

The peer's certificate will be automatically verified if
@funcref{gnutls_session_set_verify_cert} is called prior to handshake.

Alternatively, one must set a callback function during the handshake
using @funcref{gnutls_certificate_set_verify_function}, which
will verify the peer's certificate once received. The verification
should happen using @funcref{gnutls_certificate_verify_peers3} within
the callback. It will verify the certificate's signature and the owner
of the certificate. That will provide a brief verification output. If a
detailed output is required one should call @funcref{gnutls_certificate_get_peers}
to obtain the raw certificate of the peer and verify it using the
functions discussed in @ref{X.509 certificates}.

In both the automatic and the manual cases, the verification status returned
can be printed using @funcref{gnutls_certificate_verification_status_print}.

@showfuncdesc{gnutls_session_set_verify_cert}

@showfuncB{gnutls_certificate_verify_peers3,gnutls_certificate_set_verify_function}

Note that when using raw public-keys verification will not work because there is no corresponding
certificate body belonging to the raw key that can be verified. In that case the @funcref{gnutls_certificate_verify_peers}
family of functions will return a GNUTLS_E_INVALID_REQUEST error code. For authenticating raw public-keys
one must use an out-of-band mechanism, e.g. by comparing hashes or using trust on first use
(see @ref{Verifying a certificate using trust on first use authentication}).


@node Raw public-key credentials
@subsection Raw public-keys
As of version 3.6.6 GnuTLS supports @ref{Raw public-keys}. With raw public-keys only the
public-key part (that is normally embedded in a certificate) is transmitted to the peer.
In order to load a raw public-key and its corresponding private key in a credentials
structure one can use the following functions.

@showfuncC{gnutls_certificate_set_key,gnutls_certificate_set_rawpk_key_mem,gnutls_certificate_set_rawpk_key_file}


@node SRP credentials
@subsection SRP

The initialization functions in SRP credentials differ between
client and server.
Clients supporting @acronym{SRP} should set the username and password
prior to connection, to the credentials structure.
Alternatively @funcref{gnutls_srp_set_client_credentials_function}
may be used instead, to specify a callback function that should return the
SRP username and password.
The callback is called once during the @acronym{TLS} handshake.

@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}

@showfuncdesc{gnutls_srp_set_client_credentials_function}

In server side the default behavior of @acronym{GnuTLS} is to read
the usernames and @acronym{SRP} verifiers from password files. These
password file format is compatible the with the @emph{Stanford srp libraries}
format.  If a different password file format is to be used, then
@funcref{gnutls_srp_set_server_credentials_function} should be called,
to set an appropriate callback.

@showfuncdesc{gnutls_srp_set_server_credentials_file}

@showfuncdesc{gnutls_srp_set_server_credentials_function}


@node PSK credentials
@subsection PSK
The initialization functions in PSK credentials differ between
client and server.

@showfuncD{gnutls_psk_allocate_server_credentials,gnutls_psk_allocate_client_credentials,gnutls_psk_free_server_credentials,gnutls_psk_free_client_credentials}

Clients supporting @acronym{PSK} should supply the username and key
before a TLS session is established.  Alternatively
@funcref{gnutls_psk_set_client_credentials_function} can be used to
specify a callback function. This has the
advantage that the callback will be called only if @acronym{PSK} has
been negotiated.

@showfuncA{gnutls_psk_set_client_credentials}

@showfuncdesc{gnutls_psk_set_client_credentials_function}

In server side the default behavior of @acronym{GnuTLS} is to read
the usernames and @acronym{PSK} keys from a password file. The
password file should contain usernames and keys in hexadecimal
format. The name of the password file can be stored to the credentials
structure by calling @funcref{gnutls_psk_set_server_credentials_file}.  If
a different password file format is to be used, then
a callback should be set instead by @funcref{gnutls_psk_set_server_credentials_function}.

The server can help the client chose a suitable username and password,
by sending a hint. Note that there is no common profile for the PSK hint and applications
are discouraged to use it.
A server, may specify the hint by calling
@funcref{gnutls_psk_set_server_credentials_hint}.  The client can retrieve
the hint, for example in the callback function, using
@funcref{gnutls_psk_client_get_hint}.

@showfuncdesc{gnutls_psk_set_server_credentials_file}

@showfuncC{gnutls_psk_set_server_credentials_function,gnutls_psk_set_server_credentials_hint,gnutls_psk_client_get_hint}

@node Anonymous credentials
@subsection Anonymous
The key exchange methods for anonymous authentication
since GnuTLS 3.6.0 will utilize the RFC7919 parameters, unless
explicit parameters have been provided and associated with an
anonymous credentials structure. Check @ref{Parameter generation} for more information.
The initialization functions for the credentials are shown below.

@showfuncD{gnutls_anon_allocate_server_credentials,gnutls_anon_allocate_client_credentials,gnutls_anon_free_server_credentials,gnutls_anon_free_client_credentials}



@node Setting up the transport layer
@section Setting up the transport layer

The next step is to setup the underlying transport layer details. The
Berkeley sockets are implicitly used by GnuTLS, thus a
call to @funcref{gnutls_transport_set_int} would be sufficient to
specify the socket descriptor.

@showfuncB{gnutls_transport_set_int,gnutls_transport_set_int2}

If however another transport layer than TCP is selected, then
a pointer should be used instead to express the parameter to be
passed to custom functions. In that case the following functions should
be used instead.

@showfuncB{gnutls_transport_set_ptr,gnutls_transport_set_ptr2}

Moreover all of the following push and pull callbacks should be set.

@showfuncdesc{gnutls_transport_set_push_function}
@showfuncdesc{gnutls_transport_set_vec_push_function}
@showfuncdesc{gnutls_transport_set_pull_function}
@showfuncdesc{gnutls_transport_set_pull_timeout_function}


The functions above accept a callback function which
should return the number of bytes written, or -1 on
error and should set @code{errno} appropriately.
In some environments, setting @code{errno} is unreliable. For example
Windows have several errno variables in different CRTs, or in other
systems it may be a non thread-local variable.  If this is a concern to
you, call @funcref{gnutls_transport_set_errno} with the intended errno
value instead of setting @code{errno} directly.

@showfuncdesc{gnutls_transport_set_errno}

@acronym{GnuTLS} currently only interprets the EINTR, EAGAIN and EMSGSIZE errno
values and returns the corresponding @acronym{GnuTLS} error codes:
@itemize
@item @code{GNUTLS_E_INTERRUPTED}
@item @code{GNUTLS_E_AGAIN}
@item @code{GNUTLS_E_LARGE_PACKET}
@end itemize
The EINTR and EAGAIN values are returned by interrupted system calls,
or when non blocking IO is used.  All @acronym{GnuTLS} functions can be
resumed (called again), if any of the above error codes is returned. The
EMSGSIZE value is returned when attempting to send a large datagram.

In the case of DTLS it is also desirable to override the generic
transport functions with functions that emulate the operation
of @code{recvfrom} and @code{sendto}. In addition
@acronym{DTLS} requires timers during the receive of a handshake
message, set using the @funcref{gnutls_transport_set_pull_timeout_function}
function. To check the retransmission timers the function
@funcref{gnutls_dtls_get_timeout} is provided, which returns the time
remaining until the next retransmission, or better the time until
@funcref{gnutls_handshake} should be called again.

@showfuncdesc{gnutls_transport_set_pull_timeout_function}
@showfuncdesc{gnutls_dtls_get_timeout}

@menu
* Asynchronous operation::
* Reducing round-trips::
* Zero-roundtrip mode::
* Anti-replay protection::
* DTLS sessions::
* DTLS and SCTP::
@end menu

@node Asynchronous operation
@subsection Asynchronous operation

@acronym{GnuTLS} can be used with asynchronous socket or event-driven programming.
The approach is similar to using Berkeley sockets under such an environment.
The blocking, due to network interaction, calls such as
@funcref{gnutls_handshake}, @funcref{gnutls_record_recv},
can be set to non-blocking by setting the underlying sockets to non-blocking.
If other push and pull functions are setup, then they should behave the same
way as @funcintref{recv} and @funcintref{send} when used in a non-blocking
way, i.e., return -1 and set errno to @code{EAGAIN}. Since, during a TLS protocol session
@acronym{GnuTLS} does not block except for network interaction, the non blocking
@code{EAGAIN} errno will be propagated and @acronym{GnuTLS} functions
will return the @code{GNUTLS_E_AGAIN} error code. Such calls can be resumed the
same way as a system call would.
The only exception is @funcref{gnutls_record_send},
which if interrupted subsequent calls need not to include the data to be
sent (can be called with NULL argument).

When using the @funcintref{poll} or @funcintref{select} system calls though, one should remember
that they only apply to the kernel sockets API. To check for any
available buffered data in a @acronym{GnuTLS} session,
utilize @funcref{gnutls_record_check_pending},
either before the @funcintref{poll} system call, or after a call to
@funcref{gnutls_record_recv}. Data queued by @funcref{gnutls_record_send}
(when interrupted) can be discarded using @funcref{gnutls_record_discard_queued}.

An example of GnuTLS' usage with asynchronous operation can be found
in @code{doc/examples/tlsproxy}.

The following paragraphs describe the detailed requirements for non-blocking
operation when using the TLS or DTLS protocols.

@subsubsection TLS protocol
There are no special requirements for the TLS protocol operation in non-blocking
mode if a non-blocking socket is used.

It is recommended, however, for future compatibility, when in non-blocking mode, to
call the @funcref{gnutls_init} function with the
@code{GNUTLS_NONBLOCK} flag set (see @ref{Session initialization}).

@subsubsection Datagram TLS protocol
When in non-blocking mode the function, the @funcref{gnutls_init} function
must be called with the @code{GNUTLS_NONBLOCK} flag set (see @ref{Session initialization}).

In contrast with the TLS protocol, the pull timeout function is required,
but will only be called with a timeout of zero. In that case it should indicate
whether there are data to be received or not. When not using the default pull function,
then @funcref{gnutls_transport_set_pull_timeout_function} should be called.

Although in the TLS protocol implementation each call to receive or send
function implies to restoring the same function that was interrupted, in
the DTLS protocol this requirement isn't true.
There are cases where a retransmission is required, which are indicated by
a received message and thus @funcref{gnutls_record_get_direction} must be called
to decide which direction to check prior to restoring a function call.
@showfuncdesc{gnutls_record_get_direction}

When calling @funcref{gnutls_handshake} through a multi-plexer,
to be able to handle properly the DTLS handshake retransmission timers,
the function @funcref{gnutls_dtls_get_timeout}
should be used to estimate when to call @funcref{gnutls_handshake} if
no data have been received.

@node Reducing round-trips
@subsection Reducing round-trips

The full TLS 1.2 handshake requires 2 round-trips to complete, and when
combined with TCP's SYN and SYN-ACK negotiation it extends to 3 full
round-trips. While, TLS 1.3 reduces that to two round-trips when under TCP,
it still adds considerable latency, making the protocol unsuitable for
certain applications.

To optimize the handshake latency, in client side, it is possible to take
advantage of the TCP fast open @xcite{RFC7413} mechanism on operating
systems that support it. That can be done either by manually crafting the push and pull
callbacks, or by utilizing @funcref{gnutls_transport_set_fastopen}. In that
case the initial TCP handshake is eliminated, reducing the TLS 1.2 handshake round-trip
to 2, and the TLS 1.3 handshake to a single round-trip.
Note, that when this function is used, any connection failures will be reported during the
@funcref{gnutls_handshake} function call with error code @code{GNUTLS_E_PUSH_ERROR}.

@showfuncdesc{gnutls_transport_set_fastopen}

When restricted to TLS 1.2, and non-resumed sessions, it is possible to further
reduce the round-trips to a single one by taking advantage of the @ref{False Start}
TLS extension. This can be enabled by setting the @acronym{GNUTLS_ENABLE_FALSE_START}
flag on @funcref{gnutls_init}.

Under TLS 1.3, the server side can start transmitting before the handshake
is complete (i.e., while the client Finished message is still in flight),
when no client certificate authentication is requested. This, unlike false
start, is part of protocol design with no known security implications.
It can be enabled by setting the @acronym{GNUTLS_ENABLE_EARLY_START} on
@funcref{gnutls_init}, and the @funcref{gnutls_handshake} function will
return early, allowing the server to send data earlier.


@node Zero-roundtrip mode
@subsection Zero-roundtrip mode

Under TLS 1.3, when the client has already connected to the server and
is resuming a session, it can start transmitting application data during
handshake.  This is called zero round-trip time (0-RTT) mode, and the
application data sent in this mode is called early data.  The client can
send early data with @funcref{gnutls_record_send_early_data}.  The
client should call this function before calling
@funcref{gnutls_handshake} and after calling
@funcref{gnutls_session_set_data}.

Note, however, that early data has weaker security properties than
normal application data sent after handshake, such as lack of forward
secrecy, no guarantees of non-replay between connections.  Thus it is
disabled on the server side by default.  To enable it, the server
needs to:
@enumerate
@item Set @acronym{GNUTLS_ENABLE_EARLY_DATA} on @funcref{gnutls_init}.  Note that this option only has effect on server.

@item Enable anti-replay measure.  See @ref{Anti-replay protection} for the details.
@end enumerate

The server caches the received early data until it is read.  To set the
maximum amount of data to be stored in the cache, use
@funcref{gnutls_record_set_max_early_data_size}.  After receiving the
EndOfEarlyData handshake message, the server can start retrieving the
received data with @funcref{gnutls_record_recv_early_data}.  You can
call the function either after the handshake is complete, or through a
handshake hook (@funcref{gnutls_handshake_set_hook_function}).

When sending early data, the client should respect the maximum amount
of early data, which may have been previously advertised by the
server.  It can be checked using
@funcref{gnutls_record_get_max_early_data_size}, right after calling
@funcref{gnutls_session_set_data}.

After sending early data, to check whether the sent early data was
accepted by the server, use @funcref{gnutls_session_get_flags} and
compare the result with @acronym{GNUTLS_SFLAGS_EARLY_DATA}.
Similarly, on the server side, the same function and flag can be used
to check whether it has actually accepted early data.