diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2010-05-23 19:01:00 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2010-06-03 19:54:53 +0200 |
commit | c4460a9921013a9700656d55f3c701e0fed5cd2d (patch) | |
tree | 483b2af65bc81c4d3e257c097536675fb4d14b65 /doc/cha-internals.texi | |
parent | d4a4643dbe1bd739e55706fa4affaf10aae1dfa9 (diff) | |
download | gnutls-c4460a9921013a9700656d55f3c701e0fed5cd2d.tar.gz |
Documentation updates. Separated big gnutls.texi to chapter to allow easier
maintainance.
Diffstat (limited to 'doc/cha-internals.texi')
-rw-r--r-- | doc/cha-internals.texi | 336 |
1 files changed, 336 insertions, 0 deletions
diff --git a/doc/cha-internals.texi b/doc/cha-internals.texi new file mode 100644 index 0000000000..fda6221699 --- /dev/null +++ b/doc/cha-internals.texi @@ -0,0 +1,336 @@ +@node Internal architecture of GnuTLS +@chapter Internal Architecture of GnuTLS +@cindex Internal architecture + +This chapter is to give a brief description of the +way @acronym{GnuTLS} works. The focus is to give an idea +to potential developers and those who want to know what +happens inside the black box. + +@menu +* The TLS Protocol:: +* TLS Handshake Protocol:: +* TLS Authentication Methods:: +* TLS Extension Handling:: +* Certificate Handling:: +* Cryptographic Backend:: +@end menu + +@node The TLS Protocol +@section The TLS Protocol +The main needs for the TLS protocol to be used are +shown in the image below. + +@image{gnutls-client-server-use-case,9cm} + +This is being accomplished by the following object diagram. +Note that since @acronym{GnuTLS} is being developed in C +object are just structures with attributes. The operations listed +are functions that require the first parameter to be that object. +@image{gnutls-objects,15cm} + +@node TLS Handshake Protocol +@section TLS Handshake Protocol +The @acronym{GnuTLS} handshake protocol is implemented as a state +machine that waits for input or returns immediately when the non-blocking +transport layer functions are used. The main idea is shown in the following +figure. + +@image{gnutls-handshake-state,9cm} + +Also the way the input is processed varies per ciphersuite. Several +implementations of the internal handlers are available and +@ref{gnutls_handshake} only multiplexes the input to the appropriate +handler. For example a @acronym{PSK} ciphersuite has a different +implementation of the @code{process_client_key_exchange} than a +certificate ciphersuite. + +@image{gnutls-handshake-sequence,12cm} + +@node TLS Authentication Methods +@section TLS Authentication Methods +In @acronym{GnuTLS} authentication methods can be implemented quite +easily. Since the required changes to add a new authentication method +affect only the handshake protocol, a simple interface is used. An +authentication method needs only to implement the functions as seen in +the figure below. + +@image{gnutls-mod_auth_st,12cm} + +The functions that need to be implemented are the ones responsible for +interpreting the handshake protocol messages. It is common for such +functions to read data from one or more @code{credentials_t} +structures@footnote{such as the +@code{gnutls_certificate_credentials_t} structures} and write data, +such as certificates, usernames etc. to @code{auth_info_t} structures. + +Simple examples of existing authentication methods can be seen in +@code{auth_psk.c} for PSK ciphersuites and @code{auth_srp.c} for SRP +ciphersuites. After implementing these functions the structure holding +its pointers has to be registered in @code{gnutls_algorithms.c} in the +@code{_gnutls_kx_algorithms} structure. + +@node TLS Extension Handling +@section TLS Extension Handling +As with authentication methods, the TLS extensions handlers can be +implemented using the following interface. + +@image{gnutls-extensions_st,12cm} + +Here there are two functions, one for receiving the extension data +and one for sending. These functions have to check internally whether +they operate in client or server side. + +A simple example of an extension handler can be seen in +@code{ext_srp.c} After implementing these functions, together with the +extension number they handle, they have to be registered in +@code{gnutls_extensions.c} in the @code{_gnutls_extensions} structure. + +@subsection Adding a New TLS Extension + +Adding support for a new TLS extension is done from time to time, and +the process to do so is not difficult. Here are the steps you need to +follow if you wish to do this yourself. For sake of discussion, let's +consider adding support for the hypothetical TLS extension +@code{foobar}. + +@enumerate + +@item Add @code{configure} option like @code{--enable-foobar} or @code{--disable-foobar}. + +Which to chose depends on whether you intend to make the extension be +enabled by default. Look at existing checks (i.e., SRP, authz) for +how to model the code. For example: + +@example +AC_MSG_CHECKING([whether to disable foobar support]) +AC_ARG_ENABLE(foobar, + AS_HELP_STRING([--disable-foobar], + [disable foobar support]), + ac_enable_foobar=no) +if test x$ac_enable_foobar != xno; then + AC_MSG_RESULT(no) + AC_DEFINE(ENABLE_FOOBAR, 1, [enable foobar]) +else + ac_full=0 + AC_MSG_RESULT(yes) +fi +AM_CONDITIONAL(ENABLE_FOOBAR, test "$ac_enable_foobar" != "no") +@end example + +These lines should go in @code{lib/m4/hooks.m4}. + +@item Add IANA extension value to @code{extensions_t} in @code{gnutls_int.h}. + +A good name for the value would be GNUTLS_EXTENSION_FOOBAR. Check +with @url{http://www.iana.org/assignments/tls-extensiontype-values} +for allocated values. For experiments, you could pick a number but +remember that some consider it a bad idea to deploy such modified +version since it will lead to interoperability problems in the future +when the IANA allocates that number to someone else, or when the +foobar protocol is allocated another number. + +@item Add an entry to @code{_gnutls_extensions} in @code{gnutls_extensions.c}. + +A typical entry would be: + +@example + int ret; + + /* ... + */ + +#if ENABLE_FOOBAR + ret = gnutls_ext_register (GNUTLS_EXTENSION_FOOBAR, + "FOOBAR", + GNUTLS_EXT_TLS, + _gnutls_foobar_recv_params, + _gnutls_foobar_send_params); + if (ret != GNUTLS_E_SUCCESS) + return ret; +#endif +@end example + +The GNUTLS_EXTENSION_FOOBAR is the integer value you added to +@code{gnutls_int.h} earlier. The two functions are new functions that +you will need to implement, most likely you'll need to add an +@code{#include "ext_foobar.h"} as well. + +@item Add new files @code{ext_foobar.c} and @code{ext_foobar.h} that implements the extension. + +The functions you are responsible to add are those mentioned in the +previous step. As a starter, you could add this: + +@example +int +_gnutls_foobar_recv_params (gnutls_session_t session, + const opaque * data, + size_t data_size) +@{ + return 0; +@} + +int +_gnutls_foobar_send_params (gnutls_session_t session, + opaque * data, + size_t _data_size) +@{ + return 0; +@} +@end example + +The @code{_gnutls_foobar_recv_params} function is responsible for +parsing incoming extension data (both in the client and server). + +The @code{_gnutls_foobar_send_params} function is responsible for +sending extension data (both in the client and server). + +If you receive length fields that doesn't match, return +@code{GNUTLS_E_UNEXPECTED_PACKET_LENGTH}. If you receive invalid +data, return @code{GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER}. You can use +other error codes too. Return 0 on success. + +The function typically store some information in the @code{session} +variable for later usage. If you need to add new fields there, check +@code{tls_ext_st} in @code{gnutls_int.h} and compare with existing TLS +extension specific variables. + +Recall that both the client and server both send and receives +parameters, and your code most likely will need to do different things +depending on which mode it is in. It may be useful to make this +distinction explicit in the code. Thus, for example, a better +template than above would be: + +@example +int +_gnutls_foobar_recv_params (gnutls_session_t session, + const opaque * data, + size_t data_size) +@{ + if (session->security_parameters.entity == GNUTLS_CLIENT) + return foobar_recv_client (session, data, data_size); + else + return foobar_recv_server (session, data, data_size); +@} + +int +_gnutls_foobar_send_params (gnutls_session_t session, + opaque * data, + size_t data_size) +@{ + if (session->security_parameters.entity == GNUTLS_CLIENT) + return foobar_send_client (session, data, data_size); + else + return foobar_send_server (session, data, data_size); +@} +@end example + +The functions used would be declared as @code{static} functions, of +the appropriate prototype, in the same file. + +When adding the files, you'll need to add them to @code{Makefile.am} +as well, for example: + +@example +if ENABLE_FOOBAR +COBJECTS += ext_foobar.c +HFILES += ext_foobar.h +endif +@end example + +@item Add API functions to enable/disable the extension. + +Normally the client will have one API to request use of the extension, +and setting some extension specific data. The server will have one +API to let the library know that it is willing to accept the +extension, often this is implemented through a callback but it doesn't +have to. + +The APIs need to be added to @code{includes/gnutls/gnutls.h} or +@code{includes/gnutls/extra.h} as appropriate. It is recommended that +if you don't have a requirement to use the LGPLv2.1+ license for your +extension, that you place your work under the GPLv3+ license and thus +in the libgnutls-extra library. + +You can implement the API function in the @code{ext_foobar.c} file, or +if that file ends up becoming rather larger, add a +@code{gnutls_foobar.c} file. + +To make the API available in the shared library you need to add the +symbol in @code{lib/libgnutls.map} or +@code{libextra/libgnutls-extra.map} as appropriate, so that the symbol +is exported properly. + +When writing GTK-DOC style documentation for your new APIs, don't +forget to add @code{Since:} tags to indicate the GnuTLS version the +API was introduced in. + +@end enumerate + +@node Certificate Handling +@section Certificate Handling +What is provided by the certificate handling functions +is summarized in the following diagram. + +@image{gnutls-certificate-user-use-case,12cm} + +@node Cryptographic Backend +@section Cryptographic Backend +Several new systems provide hardware assisted cryptographic algorithm +implementations that offer implementations some orders of magnitude +faster than the software. For this reason GnuTLS supports by default +the /dev/crypto device usually found in FreeBSD and OpenBSD system, to +take advantage of installed hardware. + +In addition it is possible to override parts of the crypto backend or the +whole. It is possible to override them both at runtime and compile +time, however here we will discuss the runtime possibility. The API +available for this functionality is in @code{gnutls/crypto.h} header +file. + +@subsection Override specific algorithms +When an optimized implementation of a single algorithm is available, +say a hardware assisted version of @acronym{AES-CBC} then the +following functions can be used to register those algorithms. + +@itemize + +@item @ref{gnutls_crypto_single_cipher_register2} +To register a cipher algorithm. + +@ref{gnutls_crypto_single_digest_register2} +To register a hash (digest) or MAC algorithm. + +@end itemize + +Those registration functions will only replace the specified algorithm +and leave the rest of subsystem intact. + +@subsection Override parts of the backend +In some systems, such as embedded ones, it might be desirable to +override big parts of the cryptographic backend, or even all of +them. For this reason the following functions are provided. + +@itemize + +@item @ref{gnutls_crypto_cipher_register2} +To override the cryptographic algorithms backend. + +@item @ref{gnutls_crypto_digest_register2} +To override the digest algorithms backend. + +@item @ref{gnutls_crypto_rnd_register2} +To override the random number generator backend. + +@item @ref{gnutls_crypto_bigint_register2} +To override the big number number operations backend. + +@item @ref{gnutls_crypto_pk_register2} +To override the public key encryption backend. This is tight to the +big number operations so either both of them should be updated or care +must be taken to use the same format. + +@end itemize + +If all of them are used then GnuTLS will no longer use libgcrypt. + |