@node How to use GnuTLS in applications @chapter How to use @acronym{GnuTLS} in applications @anchor{examples} @cindex example programs @cindex examples @menu * Preparation:: * TLS and DTLS sessions:: * Priority Strings:: * Client examples:: * Server examples:: * Miscellaneous examples:: * Advanced and other topics:: * Using the cryptographic library:: @end menu @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. The extra functionality of the @acronym{GnuTLS-extra} library is available by including the header file @file{gnutls/extra.h} in your programs. @node Initialization @subsection Initialization GnuTLS must be initialized before it can be used. The library is initialized by calling @funcref{gnutls_global_init}. The resources allocated by the initialization process can be released if the application no longer has a need to call GnuTLS functions, this is done by calling @funcref{gnutls_global_deinit}. The extra functionality of the @acronym{GnuTLS-extra} library is available after calling @funcref{gnutls_global_init_extra}. In order to take advantage of the internationalization features in GnuTLS, such as translated error messages, the application must set 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}. @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: @smallexample gcc -c foo.c `pkg-config gnutls --cflags` @end smallexample 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}. @smallexample gcc -o foo foo.o `pkg-config gnutls --libs` @end smallexample Of course you can also combine both examples to a single command by specifying both options to @command{pkg-config}: @smallexample gcc -o foo foo.c `pkg-config gnutls --cflags --libs` @end smallexample @node TLS and DTLS sessions @section TLS and DTLS sessions @subsection 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 methods}). 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} 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_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} (see @ref{Authentication methods}). @subsection 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_ptr2} would be sufficient to specify the socket descriptor. @showfuncdesc{gnutls_transport_set_ptr2} @showfuncA{gnutls_transport_set_ptr} If however another transport layer than TCP is selected, then the following functions have to be specified. @showfuncdesc{gnutls_transport_set_push_function} @showfuncdesc{gnutls_transport_set_vec_push_function} @showfuncdesc{gnutls_transport_set_pull_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 and EAGAIN errno values and returns the corresponding @acronym{GnuTLS} error codes: @itemize @item @code{GNUTLS_E_INTERRUPTED} @item @code{GNUTLS_E_AGAIN} @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. 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. This requires the following function to be used. @showfuncdesc{gnutls_transport_set_pull_timeout_function} @subsection Handshake Once a session has been initialized and a network connection has been set up, TLS and DTLS protocols perform a handshake. The handshake is the actual key exchange. @showfuncdesc{gnutls_handshake} The handshake process doesn't ensure the verification of the peer's identity. When certificates are in use, this can be done, either after the handshake is complete, or during the handshake if @funcref{gnutls_certificate_set_verify_function} has been used. In both cases the following function can be used to verify the peer's certificate (see @ref{Certificate authentication} for more information). @showfuncA{gnutls_certificate_verify_peers2} @subsection Data transfer and termination Once the handshake is complete and peer's identity has been verified data can be exchanged. The available functions resemble the POSIX @code{recv} and @code{send} functions. @showfuncdesc{gnutls_record_send} @showfuncdesc{gnutls_record_recv} In DTLS it is adviceable to use the extended receive function shown below, because it allows the extraction of the sequence number. This is required in DTLS because messages may arrive out of order. @showfuncdesc{gnutls_record_recv_seq} A helper function is available to check whether data to be read are pending in a @acronym{GnuTLS} session. This is the equivalent of @code{select} in @acronym{POSIX} systems. @showfuncdesc{gnutls_record_check_pending} Once a TLS or DTLS session is no longer needed, it is recommended to use @funcref{gnutls_bye} to terminate the session. That way the peer is notified securely about the intention of termination, which allows distinguishing it from a malicious connection termination. @showfuncdesc{gnutls_bye} A session can be deinitialized using the following function. @showfuncdesc{gnutls_deinit} @subsection Asynchronous operation @acronym{GnuTLS} can be used with asynchronous socket or event-driven programming. During a TLS protocol session @acronym{GnuTLS} does not block for anything except calculations. The only blocking operations are due to the transport layer (sockets) functions. Those, however, in an asynchronous scenario are typically set to non-blocking mode, which forces them to return @code{EAGAIN} error code instead of blocking. In that case @acronym{GnuTLS} functions will return the @code{GNUTLS_E_AGAIN} error code and 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). The @funcintref{select} system call can also be used in combination with the @acronym{GnuTLS} functions. @funcintref{select} allows monitoring of sockets and notifies on them being ready for reading or writing data. Note however that this system call cannot notify on data present in @acronym{GnuTLS} read buffers, it is only applicable to the kernel sockets API. Thus if you are using it for reading from a @acronym{GnuTLS} session, make sure the session is read completely. That can be achieved by checking there are no data waiting to be read (using @funcref{gnutls_record_check_pending}), either before the @funcintref{select} system call, or after a call to @funcref{gnutls_record_recv}. @acronym{GnuTLS} does not keep a write buffer, thus when writing @funcintref{select} need only to be consulted. In the DTLS, however, @acronym{GnuTLS} might block due to timers required by the protocol. To prevent those timers from blocking a DTLS handshake, the @funcref{gnutls_init} should be called with the @code{GNUTLS_NONBLOCK} flag (see @ref{TLS and DTLS sessions}). @subsection DTLS sessions Because datagram TLS can operate over connections where the peer of a server cannot be reliably verified, functionality is available to prevent denial of service attacks. @acronym{GnuTLS} requires a server 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.}. That cookie is sent to the client using @funcref{gnutls_dtls_cookie_send}, and the client must reply using the correct cookie. The server side should verify the initial message sent by client using @funcref{gnutls_dtls_cookie_verify}, if successful associate a session with the cookie using @funcref{gnutls_dtls_prestate_set} and proceed to a proper handshake. @showfuncdesc{gnutls_key_generate} @showfuncdesc{gnutls_dtls_cookie_send} @showfuncdesc{gnutls_dtls_cookie_verify} @showfuncdesc{gnutls_dtls_prestate_set} Note that the above apply to server side only and they are not mandatory to be used. Not using them, however, allows denial of service attacks. The client side cookie handling is part of @funcref{gnutls_handshake}. Datagrams are typically restricted by a maximum transfer unit (MTU). For that both client and server side should set the correct maximum transfer unit for the layer underneath @acronym{GnuTLS}. This would allow proper fragmentation of DTLS messages and prevent messages from being silently discarded by the transport layer. The ``correct'' maximum transfer unit can be obtained through a path MTU discovery mechanism @xcite{RFC4821}. @showfuncdesc{gnutls_dtls_set_mtu} @showfuncdesc{gnutls_dtls_get_mtu} @showfuncdesc{gnutls_dtls_get_data_mtu} @node Priority Strings @section Priority strings In order to specify cipher suite preferences on client or server side, the previously mentioned priority functions accept a string that specifies the enabled for the handshake algorithms. That string may contain some high level keyword such as the keywords in @ref{tab:prio-keywords} or it might contain special keywords, to be explained later on. @showfuncD{gnutls_priority_set_direct,gnutls_priority_init,gnutls_priority_deinit,gnutls_priority_set} @float Table,tab:prio-keywords @multitable @columnfractions .20 .70 @headitem Keyword @tab Description @item PERFORMANCE @tab All the "secure" ciphersuites are enabled, limited to 128 bit ciphers and sorted by terms of speed performance. @item NORMAL @tab Means all "secure" ciphersuites. The 256-bit ciphers are included as a fallback only. The ciphers are sorted by security margin. @item SECURE128 @tab Means all "secure" ciphersuites of security level 128-bit or more. @item SECURE192 @tab Means all "secure" ciphersuites of security level 192-bit or more. @item SUITEB128 @tab Means all the NSA Suite B cryptography (RFC5430) ciphersuites with an 128 bit security level. @item SUITEB192 @tab Means all the NSA Suite B cryptography (RFC5430) ciphersuites with an 192 bit security level. @item EXPORT @tab Means all ciphersuites are enabled, including the low-security 40 bit ciphers. @item NONE @tab Means nothing is enabled. This disables even protocols and compression methods. It should be followed by the algorithms to be enabled. @end multitable @caption{Supported priority string keywords.} @end float Unless the first keyword is "NONE" the defaults (in preference order) are for TLS protocols TLS 1.2, TLS1.1, TLS1.0, SSL3.0; for compression NULL; for certificate types X.509, OpenPGP. For key exchange algorithms when in NORMAL or SECURE levels the perfect forward secrecy algorithms take precedence of the other protocols. In all cases all the supported key exchange algorithms are enabled (except for the RSA-EXPORT which is only enabled in EXPORT level). The NONE keyword must followed by the algorithms to be enabled, and is used to provide the exact list of requested algorithms@footnote{To avoid collisions in order to specify a compression algorithm in this string you have to prefix it with "COMP-", protocol versions with "VERS-", signature algorithms with "SIGN-" and certificate types with "CTYPE-". All other algorithms don't need a prefix.}. The order with which every algorithm is specified is significant. Similar algorithms specified before others will take precedence. The individual algorithms are shown in @ref{tab:prio-algorithms} and special keywords are in @ref{tab:prio-special}. The prefixes for individual algorithms are: @table @asis @item '!' or '-' appended with an algorithm will remove this algorithm. @item "+" appended with an algorithm will add this algorithm. @end table @float Table,tab:prio-algorithms @multitable @columnfractions .20 .70 @headitem Type @tab Keywords @item Ciphers @tab AES-128-CBC, AES-256-CBC, AES-128-GCM, CAMELLIA-128-CBC, CAMELLIA-256-CBC, ARCFOUR-128, 3DES-CBC ARCFOUR-40. Catch all name is CIPHER-ALL which will add all the algorithms from NORMAL priority. @item Key exchange @tab RSA, DHE-RSA, DHE-DSS, SRP, SRP-RSA, SRP-DSS, PSK, DHE-PSK, ECDHE-RSA, ANON-ECDH, ANON-DH, RSA-EXPORT. The Catch all name is KX-ALL which will add all the algorithms from NORMAL priority. @item MAC @tab MD5, SHA1, SHA256, AEAD (used with GCM ciphers only). All algorithms from NORMAL priority can be accessed with MAC-ALL. @item Compression algorithms @tab COMP-NULL, COMP-DEFLATE. Catch all is COMP-ALL. @item TLS versions @tab VERS-SSL3.0, VERS-TLS1.0, VERS-TLS1.1, VERS-TLS1.2. Catch all is VERS-TLS-ALL. @item Signature algorithms @tab SIGN-RSA-SHA1, SIGN-RSA-SHA224, SIGN-RSA-SHA256, SIGN-RSA-SHA384, SIGN-RSA-SHA512, SIGN-DSA-SHA1, SIGN-DSA-SHA224, SIGN-DSA-SHA256, SIGN-RSA-MD5. Catch all is SIGN-ALL. This is only valid for TLS 1.2 and later. @item Elliptic curves @tab CURVE-SECP224R1, CURVE-SECP256R1, CURVE-SECP384R1, CURVE-SECP521R1. Catch all is CURVE-ALL. @end multitable @caption{The supported priority strings.} @end float @float Table,tab:prio-special @multitable @columnfractions .45 .45 @headitem Keyword @tab Description @item %COMPAT @tab will enable compatibility mode. It might mean that violations of the protocols are allowed as long as maximum compatibility with problematic clients and servers is achieved. @item %NO_EXTENSIONS @tab will prevent the sending of any TLS extensions in client side. Note that TLS 1.2 requires extensions to be used, thus this option must be used with care. @item %DISABLE_SAFE_RENEGOTIATION @tab will disable safe renegotiation completely. Do not use unless you know what you are doing. Testing purposes only. @item %UNSAFE_RENEGOTIATION @tab will allow handshakes and re-handshakes without the safe renegotiation extension. Note that for clients this mode is insecure (you may be under attack), and for servers it will allow insecure clients to connect (which could be fooled by an attacker). Do not use unless you know what you are doing and want maximum compatibility. @item %PARTIAL_RENEGOTIATION @tab will allow initial handshakes to proceed, but not re-handshakes. This leaves the client vulnerable to attack, and servers will be compatible with non-upgraded clients for initial handshakes. This is currently the default for clients and servers, for compatibility reasons. @item %SAFE_RENEGOTIATION @tab will enforce safe renegotiation. Clients and servers will refuse to talk to an insecure peer. Currently this causes interoperability problems, but is required for full protection. @item %SSL3_RECORD_VERSION @tab will use SSL3.0 record version in client hello. This is the default. @item %LATEST_RECORD_VERSION @tab will use the latest TLS version record version in client hello. @item %VERIFY_ALLOW_SIGN_RSA_MD5 @tab will allow RSA-MD5 signatures in certificate chains. @item %VERIFY_ALLOW_X509_V1_CA_CRT @tab will allow V1 CAs in chains. @end multitable @caption{Special priority string keywords.} @end float @node Client examples @section Client examples This section contains examples of @acronym{TLS} and @acronym{SSL} clients, using @acronym{GnuTLS}. Note that these examples contain little or no error checking. Some of the examples require functions implemented by another example. @menu * Simple client example with anonymous authentication:: * Simple client example with X.509 certificate support:: * Simple Datagram TLS client example:: * Obtaining session information:: * Verifying peer's certificate:: * Using a callback to select the certificate to use:: * Verifying a certificate:: * Client using a PKCS 11 token with TLS:: * Client with Resume capability example:: * Simple client example with SRP authentication:: * Simple client example in C++:: * Helper function for TCP connections:: @end menu @node Simple client example with anonymous authentication @subsection Simple client example with anonymous authentication The simplest client using TLS is the one that doesn't do any authentication. This means no external certificates or passwords are needed to set up the connection. As could be expected, the connection is vulnerable to man-in-the-middle (active or redirection) attacks. However, the data is integrity and privacy protected. @verbatiminclude examples/ex-client1.c @node Simple client example with X.509 certificate support @subsection Simple client example with @acronym{X.509} certificate support Let's assume now that we want to create a TCP client which communicates with servers that use @acronym{X.509} or @acronym{OpenPGP} certificate authentication. The following client is a very simple @acronym{TLS} client, it does not support session resuming, not even certificate verification. The TCP functions defined in this example are used in most of the other examples below, without redefining them. @verbatiminclude examples/ex-client2.c @node Simple Datagram TLS client example @subsection Simple datagram @acronym{TLS} client example This is a client that uses @acronym{UDP} to connect to a server. This is the @acronym{DTLS} equivalent to the example in @ref{Simple client example with X.509 certificate support}. @verbatiminclude examples/ex-client-udp.c @node Obtaining session information @subsection Obtaining session information Most of the times it is desirable to know the security properties of the current established session. This includes the underlying ciphers and the protocols involved. That is the purpose of the following function. Note that this function will print meaningful values only if called after a successful @funcref{gnutls_handshake}. @verbatiminclude examples/ex-session-info.c @node Verifying peer's certificate @subsection Verifying peer's certificate @anchor{ex:verify} A @acronym{TLS} session is not secure just after the handshake procedure has finished. It must be considered secure, only after the peer's certificate and identity have been verified. That is, you have to verify the signature in peer's certificate, the hostname in the certificate, and expiration dates. Just after this step you should treat the connection as being a secure one. @verbatiminclude examples/ex-rfc2818.c @node Using a callback to select the certificate to use @subsection Using a callback to select the certificate to use There are cases where a client holds several certificate and key pairs, and may not want to load all of them in the credentials structure. The following example demonstrates the use of the certificate selection callback. @verbatiminclude examples/ex-cert-select.c @node Verifying a certificate @subsection Verifying a certificate @anchor{ex:verify2} An example is listed below which uses the high level verification functions to verify a given certificate list. @verbatiminclude examples/ex-verify.c @node Client using a PKCS 11 token with TLS @subsection Using a @acronym{PKCS} #11 token with TLS @anchor{ex:pkcs11-client} This example will demonstrate how to load keys and certificates from a @acronym{PKCS} #11 token, and use it with a TLS connection. @verbatiminclude examples/ex-cert-select-pkcs11.c @node Client with Resume capability example @subsection Client with resume capability example @anchor{ex:resume-client} This is a modification of the simple client example. Here we demonstrate the use of session resumption. The client tries to connect once using @acronym{TLS}, close the connection and then try to establish a new connection using the previously negotiated data. @verbatiminclude examples/ex-client-resume.c @node Simple client example with SRP authentication @subsection Simple client example with @acronym{SRP} authentication The following client is a very simple @acronym{SRP} @acronym{TLS} client which connects to a server and authenticates using a @emph{username} and a @emph{password}. The server may authenticate itself using a certificate, and in that case it has to be verified. @verbatiminclude examples/ex-client-srp.c @node Simple client example in C++ @subsection Simple client example using the C++ API The following client is a simple example of a client client utilizing the GnuTLS C++ API. @verbatiminclude examples/ex-cxx.cpp @node Helper function for TCP connections @subsection Helper function for TCP connections This helper function abstracts away TCP connection handling from the other examples. It is required to build some examples. @verbatiminclude examples/tcp.c @node Server examples @section Server examples This section contains examples of @acronym{TLS} and @acronym{SSL} servers, using @acronym{GnuTLS}. @menu * Echo Server with X.509 authentication:: * Echo Server with OpenPGP authentication:: * Echo Server with SRP authentication:: * Echo Server with anonymous authentication:: @end menu @node Echo Server with X.509 authentication @subsection Echo server with @acronym{X.509} authentication This example is a very simple echo server which supports @acronym{X.509} authentication, using the RSA ciphersuites. @verbatiminclude examples/ex-serv1.c @node Echo Server with OpenPGP authentication @subsection Echo server with @acronym{OpenPGP} authentication @cindex @acronym{OpenPGP} server The following example is an echo server which supports @acronym{OpenPGP} key authentication. You can easily combine this functionality ---that is have a server that supports both @acronym{X.509} and @acronym{OpenPGP} certificates--- but we separated them to keep these examples as simple as possible. @verbatiminclude examples/ex-serv-pgp.c @node Echo Server with SRP authentication @subsection Echo server with @acronym{SRP} authentication This is a server which supports @acronym{SRP} authentication. It is also possible to combine this functionality with a certificate server. Here it is separate for simplicity. @verbatiminclude examples/ex-serv-srp.c @node Echo Server with anonymous authentication @subsection Echo Server with anonymous authentication This example server support anonymous authentication, and could be used to serve the example client for anonymous authentication. @verbatiminclude examples/ex-serv-anon.c @node Miscellaneous examples @section Miscellaneous examples @menu * Checking for an alert:: * X.509 certificate parsing example:: @end menu @node Checking for an alert @subsection Checking for an alert This is a function that checks if an alert has been received in the current session. @verbatiminclude examples/ex-alert.c @node X.509 certificate parsing example @subsection @acronym{X.509} certificate parsing example @anchor{ex:x509-info} To demonstrate the @acronym{X.509} parsing capabilities an example program is listed below. That program reads the peer's certificate, and prints information about it. @verbatiminclude examples/ex-x509-info.c @node Advanced and other topics @section Advanced and other topics @menu * Parameter generation:: * Keying Material Exporters:: * Channel Bindings:: * Compatibility with the OpenSSL library:: @end menu @node Parameter generation @subsection Parameter generation @cindex parameter generation @cindex generating parameters Several TLS ciphersuites require additional parameters that need to be generated or provided by the application. The Diffie-Hellman based ciphersuites (ANON-DH or DHE), require the group parameters to be provided. Those can either be be generated on the fly using @funcref{gnutls_dh_params_generate2} or imported from pregenerated data using @funcref{gnutls_dh_params_import_pkcs3}. The parameters can be used in a @acronym{TLS} session by calling @funcref{gnutls_certificate_set_dh_params} or @funcref{gnutls_anon_set_server_dh_params} for anonymous sessions. @showfuncB{gnutls_dh_params_init,gnutls_dh_params_deinit} @showfuncD{gnutls_dh_params_generate2,gnutls_dh_params_import_pkcs3,gnutls_certificate_set_dh_params,gnutls_anon_set_server_dh_params} Due to the time-consuming calculations required for the generation of Diffie-Hellman parameters we suggest against performing generation of them within an application. The @code{certtool} tool can be used to generate or export known safe values that can be stored in code or in a configuration file to provide the ability to replace. We also recommend the usage of @funcref{gnutls_sec_param_to_pk_bits} (see @ref{Selecting cryptographic key sizes}) to determine the bit size of the generated parameters. The ciphersuites that involve the RSA-EXPORT key exchange require additional parameters. Those ciphersuites are rarely used today because they are by design insecure, thus if you have no requirement for them, the rest of this section can be skipped. The RSA-EXPORT key exchange requires 512-bit RSA keys to be generated. It is recommended those parameters to be refreshed (regenerated) in short intervals. The following functions can be used for these parameters. @showfuncB{gnutls_rsa_params_init,gnutls_rsa_params_deinit} @showfuncD{gnutls_rsa_params_generate2,gnutls_certificate_set_rsa_export_params,gnutls_rsa_params_import_pkcs1,gnutls_rsa_params_export_pkcs1} To allow renewal of the parameters within an application without accessing the credentials, which are a shared structure, an alternative interface is available using a callback function. @showfuncdesc{gnutls_certificate_set_params_function} @node Keying Material Exporters @subsection Keying material exporters @cindex keying material exporters @cindex exporting keying material The TLS PRF can be used by other protocols to derive data. The API to use is @funcref{gnutls_prf}. The function needs to be provided with the label in the parameter @code{label}, and the extra data to mix in the @code{extra} parameter. Depending on whether you want to mix in the client or server random data first, you can set the @code{server_random_first} parameter. For example, after establishing a TLS session using @funcref{gnutls_handshake}, you can invoke the TLS PRF with this call: @smallexample #define MYLABEL "EXPORTER-FOO" #define MYCONTEXT "some context data" char out[32]; rc = gnutls_prf (session, strlen (MYLABEL), MYLABEL, 0, strlen (MYCONTEXT), MYCONTEXT, 32, out); @end smallexample If you don't want to mix in the client/server random, there is a more low-level TLS PRF interface called @funcref{gnutls_prf_raw}. @node Channel Bindings @subsection Channel bindings @cindex channel bindings In user authentication protocols (e.g., EAP or SASL mechanisms) it is useful to have a unique string that identifies the secure channel that is used, to bind together the user authentication with the secure channel. This can protect against man-in-the-middle attacks in some situations. That unique string is called a ``channel binding''. For background and discussion see @xcite{RFC5056}. In @acronym{GnuTLS} you can extract a channel binding using the @funcref{gnutls_session_channel_binding} function. Currently only the type @code{GNUTLS_CB_TLS_UNIQUE} is supported, which corresponds to the @code{tls-unique} channel binding for TLS defined in @xcite{RFC5929}. The following example describes how to print the channel binding data. Note that it must be run after a successful TLS handshake. @smallexample @{ gnutls_datum_t cb; int rc; rc = gnutls_session_channel_binding (session, GNUTLS_CB_TLS_UNIQUE, &cb); if (rc) fprintf (stderr, "Channel binding error: %s\n", gnutls_strerror (rc)); else @{ size_t i; printf ("- Channel binding 'tls-unique': "); for (i = 0; i < cb.size; i++) printf ("%02x", cb.data[i]); printf ("\n"); @} @} @end smallexample @node Compatibility with the OpenSSL library @subsection Compatibility with the OpenSSL library @cindex OpenSSL To ease @acronym{GnuTLS}' integration with existing applications, a compatibility layer with the OpenSSL library is included in the @code{gnutls-openssl} library. This compatibility layer is not complete and it is not intended to completely re-implement the OpenSSL API with @acronym{GnuTLS}. It only provides limited source-level compatibility. The prototypes for the compatibility functions are in the @file{gnutls/openssl.h} header file. The limitations imposed by the compatibility layer include: @itemize @item Error handling is not thread safe. @end itemize @node Using the cryptographic library @section Using the cryptographic library @acronym{GnuTLS} is not a low-level cryptographic library, i.e., it does not provide access to basic cryptographic primitives. However it abstracts the internal cryptographic back-end (see @ref{Cryptographic Backend}), providing symmetric crypto, hash and HMAC algorithms, as well access to the random number generation. @menu * Symmetric cryptography:: * Hash and HMAC functions:: * Random number generation:: @end menu @node Symmetric cryptography @subsection Symmetric cryptography @cindex symmetric cryptography The available functions to access symmetric crypto algorithms operations are shown below. The supported algorithms are the algorithms required by the TLS protocol. They are listed in @ref{tab:ciphers}. @showfuncE{gnutls_cipher_init,gnutls_cipher_encrypt2,gnutls_cipher_decrypt2,gnutls_cipher_set_iv,gnutls_cipher_deinit} In order to support authenticated encryption with associated data (AEAD) algorithms the following functions are provided to set the associated data and retrieve the authentication tag. @showfuncB{gnutls_cipher_add_auth,gnutls_cipher_tag} @node Hash and HMAC functions @subsection Hash and HMAC functions @cindex hash functions @cindex HMAC functions The available operations to access hash functions and hash-MAC (HMAC) algorithms are shown below. HMAC algorithms provided keyed hash functionality. They supported HMAC algorithms are listed in @ref{tab:macs}. @showfuncF{gnutls_hmac_init,gnutls_hmac,gnutls_hmac_output,gnutls_hmac_deinit,gnutls_hmac_get_len,gnutls_hmac_fast} The available functions to access hash functions are shown below. The supported hash functions are the same as the HMAC algorithms. @showfuncF{gnutls_hash_init,gnutls_hash,gnutls_hash_output,gnutls_hash_deinit,gnutls_hash_get_len,gnutls_hash_fast} @node Random number generation @subsection Random number generation @cindex random numbers Access to the random number generator is provided using the @funcref{gnutls_rnd} function. @showfuncdesc{gnutls_rnd}