guile: Rename to `libguile-gnutls-v-2'.
[gnutls.git] / doc / cha-internals.texi
blob2347efd8437a3f073242de6f761a19ed4fc56f4d
1 @node Internal architecture of GnuTLS
2 @chapter Internal Architecture of GnuTLS
3 @cindex internal architecture
5 This chapter is to give a brief description of the
6 way @acronym{GnuTLS} works. The focus is to give an idea
7 to potential developers and those who want to know what
8 happens inside the black box.
10 @menu
11 * The TLS Protocol::
12 * TLS Handshake Protocol::
13 * TLS Authentication Methods::
14 * TLS Extension Handling::
15 * Cryptographic Backend::
16 @end menu
18 @node The TLS Protocol
19 @section The TLS Protocol
20 The main use case for the TLS protocol is shown in @ref{fig:client-server}.
21 A user of a library implementing the protocol expects no less than this functionality,
22 i.e., to be able to set parameters such as the accepted security level, perform a
23 negotiation with the peer and be able to exchange data.
25 @float Figure,fig:client-server
26 @image{gnutls-client-server-use-case,9cm}
27 @caption{TLS protocol use case.}
28 @end float
30 @node TLS Handshake Protocol
31 @section TLS Handshake Protocol
32 The @acronym{GnuTLS} handshake protocol is implemented as a state
33 machine that waits for input or returns immediately when the non-blocking
34 transport layer functions are used. The main idea is shown in @ref{fig:gnutls-handshake}.
36 @float Figure,fig:gnutls-handshake
37 @image{gnutls-handshake-state,9cm}
38 @caption{GnuTLS handshake state machine.}
39 @end float
41 Also the way the input is processed varies per ciphersuite. Several 
42 implementations of the internal handlers are available and 
43 @funcref{gnutls_handshake} only multiplexes the input to the appropriate 
44 handler. For example a @acronym{PSK} ciphersuite has a different 
45 implementation of the @code{process_client_key_exchange} than a
46 certificate ciphersuite. We illustrate the idea in @ref{fig:gnutls-handshake-sequence}.
48 @float Figure,fig:gnutls-handshake-sequence
49 @image{gnutls-handshake-sequence,12cm}
50 @caption{GnuTLS handshake process sequence.}
51 @end float
53 @node TLS Authentication Methods
54 @section TLS Authentication Methods
55 In @acronym{GnuTLS} authentication methods can be implemented quite
56 easily.  Since the required changes to add a new authentication method
57 affect only the handshake protocol, a simple interface is used. An
58 authentication method needs to implement the functions shown below.
60 @verbatim
61 typedef struct 
63   const char *name;
64   int (*gnutls_generate_server_certificate) (gnutls_session_t, gnutls_buffer_st*);
65   int (*gnutls_generate_client_certificate) (gnutls_session_t, gnutls_buffer_st*);
66   int (*gnutls_generate_server_kx) (gnutls_session_t, gnutls_buffer_st*);
67   int (*gnutls_generate_client_kx) (gnutls_session_t, gnutls_buffer_st*);
68   int (*gnutls_generate_client_cert_vrfy) (gnutls_session_t, gnutls_buffer_st *);
69   int (*gnutls_generate_server_certificate_request) (gnutls_session_t,
70                                                      gnutls_buffer_st *);
72   int (*gnutls_process_server_certificate) (gnutls_session_t, opaque *,
73                                             size_t);
74   int (*gnutls_process_client_certificate) (gnutls_session_t, opaque *,
75                                             size_t);
76   int (*gnutls_process_server_kx) (gnutls_session_t, opaque *, size_t);
77   int (*gnutls_process_client_kx) (gnutls_session_t, opaque *, size_t);
78   int (*gnutls_process_client_cert_vrfy) (gnutls_session_t, opaque *, size_t);
79   int (*gnutls_process_server_certificate_request) (gnutls_session_t,
80                                                     opaque *, size_t);
81 } mod_auth_st;
82 @end verbatim
84 Those functions are responsible for the
85 interpretation of the handshake protocol messages. It is common for such
86 functions to read data from one or more @code{credentials_t}
87 structures@footnote{such as the
88 @code{gnutls_certificate_credentials_t} structures} and write data,
89 such as certificates, usernames etc. to @code{auth_info_t} structures.
92 Simple examples of existing authentication methods can be seen in
93 @code{auth/@-psk.c} for PSK ciphersuites and @code{auth/@-srp.c} for SRP
94 ciphersuites. After implementing these functions the structure holding
95 its pointers has to be registered in @code{gnutls_@-algorithms.c} in the
96 @code{_gnutls_@-kx_@-algorithms} structure.
98 @node TLS Extension Handling
99 @section TLS Extension Handling
100 As with authentication methods, the TLS extensions handlers can be
101 implemented using the interface shown below.
103 @verbatim
104 typedef int (*gnutls_ext_recv_func) (gnutls_session_t session,
105                                      const unsigned char *data, size_t len);
106 typedef int (*gnutls_ext_send_func) (gnutls_session_t session,
107                                      gnutls_buffer_st *extdata);
108 @end verbatim
110 Here there are two functions, one for receiving the extension data
111 and one for sending. These functions have to check internally whether
112 they operate in client or server side. 
114 A simple example of an extension handler can be seen in
115 @code{ext/@-srp.c} in GnuTLS' source code. After implementing these functions, 
116 together with the extension number they handle, they have to be registered 
117 using @funcintref{_gnutls_ext_register} in
118 @code{gnutls_extensions.c} typically within @funcintref{_gnutls_ext_init}.
120 @subsection Adding a New TLS Extension
122 Adding support for a new TLS extension is done from time to time, and
123 the process to do so is not difficult.  Here are the steps you need to
124 follow if you wish to do this yourself.  For sake of discussion, let's
125 consider adding support for the hypothetical TLS extension
126 @code{foobar}.
128 @subsubsection Add @code{configure} option like @code{--enable-foobar} or @code{--disable-foobar}.
130 This step is useful when the extension code is large and it might be desirable
131 to disable the extension under some circumstances. Otherwise it can be safely
132 skipped.
134 Whether to chose enable or disable depends on whether you intend to make the extension be
135 enabled by default.  Look at existing checks (i.e., SRP, authz) for
136 how to model the code.  For example:
138 @example
139 AC_MSG_CHECKING([whether to disable foobar support])
140 AC_ARG_ENABLE(foobar,
141         AS_HELP_STRING([--disable-foobar],
142                 [disable foobar support]),
143         ac_enable_foobar=no)
144 if test x$ac_enable_foobar != xno; then
145  AC_MSG_RESULT(no)
146  AC_DEFINE(ENABLE_FOOBAR, 1, [enable foobar])
147 else
148  ac_full=0
149  AC_MSG_RESULT(yes)
151 AM_CONDITIONAL(ENABLE_FOOBAR, test "$ac_enable_foobar" != "no")
152 @end example
154 These lines should go in @code{lib/m4/hooks.m4}.
156 @subsubsection Add IANA extension value to @code{extensions_t} in @code{gnutls_int.h}.
158 A good name for the value would be GNUTLS_EXTENSION_FOOBAR.  Check
159 with @url{http://www.iana.org/assignments/tls-extensiontype-values}
160 for allocated values.  For experiments, you could pick a number but
161 remember that some consider it a bad idea to deploy such modified
162 version since it will lead to interoperability problems in the future
163 when the IANA allocates that number to someone else, or when the
164 foobar protocol is allocated another number.
166 @subsubsection Add an entry to @code{_gnutls_extensions} in @code{gnutls_extensions.c}.
168 A typical entry would be:
170 @example
171   int ret;
173 #if ENABLE_FOOBAR
174   ret = _gnutls_ext_register (&foobar_ext);
175   if (ret != GNUTLS_E_SUCCESS)
176     return ret;
177 #endif
178 @end example
180 Most likely you'll need to add an @code{#include "ext/@-foobar.h"}, that
181 will contain something like
182 like:
183 @example
184   extension_entry_st foobar_ext = @{
185     .name = "FOOBAR",
186     .type = GNUTLS_EXTENSION_FOOBAR,
187     .parse_type = GNUTLS_EXT_TLS,
188     .recv_func = _foobar_recv_params,
189     .send_func = _foobar_send_params,
190     .pack_func = _foobar_pack,
191     .unpack_func = _foobar_unpack,
192     .deinit_func = NULL
193   @}
194 @end example
196 The GNUTLS_EXTENSION_FOOBAR is the integer value you added to
197 @code{gnutls_int.h} earlier.  In this structure you specify the
198 functions to read the extension from the hello message, the function
199 to send the reply to, and two more functions to pack and unpack from
200 stored session data (e.g. when resumming a session). The @code{deinit} function
201 will be called to deinitialize the extension's private parameters, if any.
203 Note that the conditional @code{ENABLE_FOOBAR} definition should only be 
204 used if step 1 with the @code{configure} options has taken place.
206 @subsubsection Add new files  that implement the extension.
208 The functions you are responsible to add are those mentioned in the
209 previous step.  They should be added in a file such as @code{ext/@-foobar.c} 
210 and headers should be placed in @code{ext/@-foobar.h}.
211 As a starter, you could add this:
213 @example
215 _foobar_recv_params (gnutls_session_t session, const opaque * data,
216                      size_t data_size)
218   return 0;
222 _foobar_send_params (gnutls_session_t session, gnutls_buffer_st* data)
224   return 0;
228 _foobar_pack (extension_priv_data_t epriv, gnutls_buffer_st * ps)
230    /* Append the extension's internal state to buffer */
231    return 0;
235 _foobar_unpack (gnutls_buffer_st * ps, extension_priv_data_t * epriv)
237    /* Read the internal state from buffer */
238    return 0;
240 @end example
242 The @funcintref{_foobar_recv_params} function is responsible for
243 parsing incoming extension data (both in the client and server).
245 The @funcintref{_foobar_send_params} function is responsible for
246 sending extension data (both in the client and server).
248 If you receive length fields that doesn't match, return
249 @code{GNUTLS_E_@-UNEXPECTED_@-PACKET_@-LENGTH}.  If you receive invalid
250 data, return @code{GNUTLS_E_@-RECEIVED_@-ILLEGAL_@-PARAMETER}.  You can use
251 other error codes from the list in @ref{Error codes}.  Return 0 on success.
253 An extension typically stores private information in the @code{session}
254 data for later usage. That can be done using the functions 
255 @funcintref{_gnutls_ext_set_session_data} and
256 @funcintref{_gnutls_ext_get_session_data}. You can check simple examples
257 at @code{ext/@-max_@-record.c} and @code{ext/@-server_@-name.c} extensions.
258 That private information can be saved and restored across session 
259 resumption if the following functions are set:
261 The @funcintref{_foobar_pack} function is responsible for packing
262 internal extension data to save them in the session resumption storage.
264 The @funcintref{_foobar_unpack} function is responsible for
265 restoring session data from the session resumption storage.
267 Recall that both the client and server, send and receive
268 parameters, and your code most likely will need to do different things
269 depending on which mode it is in.  It may be useful to make this
270 distinction explicit in the code.  Thus, for example, a better
271 template than above would be:
273 @example
275 _gnutls_foobar_recv_params (gnutls_session_t session,
276                             const opaque * data,
277                             size_t data_size)
279   if (session->security_parameters.entity == GNUTLS_CLIENT)
280     return foobar_recv_client (session, data, data_size);
281   else
282     return foobar_recv_server (session, data, data_size);
286 _gnutls_foobar_send_params (gnutls_session_t session,
287                             gnutls_buffer_st * data)
289   if (session->security_parameters.entity == GNUTLS_CLIENT)
290     return foobar_send_client (session, data);
291   else
292     return foobar_send_server (session, data);
294 @end example
296 The functions used would be declared as @code{static} functions, of
297 the appropriate prototype, in the same file.
298 When adding the files, you'll need to add them to @code{ext/@-Makefile.am}
299 as well, for example:
301 @example
302 if ENABLE_FOOBAR
303 libgnutls_ext_la_SOURCES += ext/foobar.c ext/foobar.h
304 endif
305 @end example
307 @subsubsection Add API functions to enable/disable the extension.
309 It might be desirable to allow users of the extension to
310 request use of the extension, or set extension specific data.  
311 This can be implemented by adding extension specific function calls
312 that can be added to @code{includes/@-gnutls/@-gnutls.h},
313 as long as the LGPLv3+ applies.
314 The implementation of the function should lie in the @code{ext/@-foobar.c} file.
316 To make the API available in the shared library you need to add the
317 symbol in @code{lib/@-libgnutls.map}, so that the symbol
318 is exported properly.
320 When writing GTK-DOC style documentation for your new APIs, don't
321 forget to add @code{Since:} tags to indicate the GnuTLS version the
322 API was introduced in.
324 @node Cryptographic Backend
325 @section Cryptographic Backend
326 Today most new processors, either for embedded or desktop systems
327 include either instructions  intended to speed up cryptographic operations,
328 or a co-processor with cryptographic capabilities. Taking advantage of 
329 those is a challenging task for every cryptographic  application or 
330 library. Unfortunately the cryptographic library that GnuTLS is based 
331 on takes no advantage of these capabilities. For this reason GnuTLS handles 
332 this internally by following a layered approach to accessing
333 cryptographic operations as in @ref{fig:crypto-layers}.
335 @float Figure,fig:crypto-layers
336 @image{gnutls-crypto-layers,12cm}
337 @caption{GnuTLS cryptographic back-end design.}
338 @end float
340 The TLS layer uses a cryptographic provider layer, that will in turn either 
341 use the default crypto provider -- a software crypto library, or use an external
342 crypto provider, if available.
344 @subsection Cryptographic library layer
345 The Cryptographic library layer, currently supports only
346 libnettle. Other cryptographic libraries might be supported
347 in the future.
349 @subsection External cryptography provider
350 Systems that include a cryptographic co-processor, typically come with
351 kernel drivers to utilize the operations from software. For this reason 
352 GnuTLS provides a layer where each individual algorithm used can be replaced
353 by another implementation, i.e., the one provided by the driver. The
354 FreeBSD, OpenBSD and Linux kernels@footnote{Check @url{http://home.gna.org/cryptodev-linux/} 
355 for the Linux kernel implementation of @code{/dev/crypto}.} include already 
356 a number of hardware assisted implementations, and also provide an interface 
357 to access them, called @code{/dev/crypto}.
358 GnuTLS will take advantage of this interface if compiled with special
359 options. That is because in most systems where hardware-assisted 
360 cryptographic operations are not available, using this interface might 
361 actually harm performance.
363 In systems that include cryptographic instructions with the CPU's
364 instructions set, using the kernel interface will introduce an
365 unneeded layer. For this reason GnuTLS includes such optimizations
366 found in popular processors such as the AES-NI or VIA PADLOCK instruction sets.
367 This is achieved using a mechanism that detects CPU capabilities and
368 overrides parts of crypto backend at runtime.
369 The next section discusses the registration of a detected algorithm
370 optimization. For more information please consult the @acronym{GnuTLS}
371 source code in @code{lib/accelerated/}.
373 @subsubsection Overriding specific algorithms
374 When an optimized implementation of a single algorithm is available,
375 say a hardware assisted version of @acronym{AES-CBC} then the
376 following (internal) functions, from @code{crypto-backend.h}, can 
377 be used to register those algorithms.
379 @itemize
381 @item @code{gnutls_crypto_single_cipher_register}:
382 To register a cipher algorithm.
384 @item @code{gnutls_crypto_single_digest_register}:
385 To register a hash (digest) or MAC algorithm.
387 @end itemize
389 Those registration functions will only replace the specified algorithm
390 and leave the rest of subsystem intact.
392 @subsubsection Overriding the cryptographic library
393 In some systems, that might contain a broad acceleration engine, it 
394 might be desirable to override big parts of the cryptographic backend, 
395 or even all of them. T following functions are provided for this reason.
397 @itemize
399 @item @code{gnutls_crypto_cipher_register}:
400 To override the cryptographic algorithms backend.
402 @item @code{gnutls_crypto_digest_register}:
403 To override the digest algorithms backend.
405 @item @code{gnutls_crypto_rnd_register}:
406 To override the random number generator backend.
408 @item @code{gnutls_crypto_bigint_register}:
409 To override the big number number operations backend.
411 @item @code{gnutls_crypto_pk_register}:
412 To override the public key encryption backend. This is tied to the
413 big number operations so either none or both of them should be overriden.
415 @end itemize