Tizen 2.0 Release
[external/libgnutls26.git] / doc / cha-internals.texi
1 @node Internal architecture of GnuTLS
2 @chapter Internal Architecture of GnuTLS
3 @cindex Internal architecture
4
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.
9
10 @menu
11 * The TLS Protocol::
12 * TLS Handshake Protocol::
13 * TLS Authentication Methods::
14 * TLS Extension Handling::
15 * Certificate Handling::
16 * Cryptographic Backend::
17 @end menu
18
19 @node The TLS Protocol
20 @section The TLS Protocol
21 The main needs for the TLS protocol to be used are
22 shown in the image below.
23
24 @image{gnutls-client-server-use-case,9cm}
25
26 This is being accomplished by the following object diagram.
27 Note that since @acronym{GnuTLS} is being developed in C
28 object are just structures with attributes. The operations listed
29 are functions that require the first parameter to be that object.
30 @image{gnutls-objects,15cm}
31
32 @node TLS Handshake Protocol
33 @section TLS Handshake Protocol
34 The @acronym{GnuTLS} handshake protocol is implemented as a state
35 machine that waits for input or returns immediately when the non-blocking
36 transport layer functions are used. The main idea is shown in the following
37 figure.
38
39 @image{gnutls-handshake-state,9cm}
40
41 Also the way the input is processed varies per ciphersuite. Several 
42 implementations of the internal handlers are available and 
43 @ref{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.
47
48 @image{gnutls-handshake-sequence,12cm}
49
50 @node TLS Authentication Methods
51 @section TLS Authentication Methods
52 In @acronym{GnuTLS} authentication methods can be implemented quite
53 easily.  Since the required changes to add a new authentication method
54 affect only the handshake protocol, a simple interface is used. An
55 authentication method needs only to implement the functions as seen in
56 the figure below.
57
58 @image{gnutls-mod_auth_st,12cm}
59
60 The functions that need to be implemented are the ones responsible for
61 interpreting the handshake protocol messages. It is common for such
62 functions to read data from one or more @code{credentials_t}
63 structures@footnote{such as the
64 @code{gnutls_certificate_credentials_t} structures} and write data,
65 such as certificates, usernames etc. to @code{auth_info_t} structures.
66
67 Simple examples of existing authentication methods can be seen in
68 @code{auth_psk.c} for PSK ciphersuites and @code{auth_srp.c} for SRP
69 ciphersuites. After implementing these functions the structure holding
70 its pointers has to be registered in @code{gnutls_algorithms.c} in the
71 @code{_gnutls_kx_algorithms} structure.
72
73 @node TLS Extension Handling
74 @section TLS Extension Handling
75 As with authentication methods, the TLS extensions handlers can be
76 implemented using the following interface.
77
78 @image{gnutls-extensions_st,12cm}
79
80 Here there are two functions, one for receiving the extension data
81 and one for sending. These functions have to check internally whether
82 they operate in client or server side. 
83
84 A simple example of an extension handler can be seen in
85 @code{ext_srp.c} After implementing these functions, together with the
86 extension number they handle, they have to be registered in
87 @code{gnutls_extensions.c} in the @code{_gnutls_extensions} structure.
88
89 @subsection Adding a New TLS Extension
90
91 Adding support for a new TLS extension is done from time to time, and
92 the process to do so is not difficult.  Here are the steps you need to
93 follow if you wish to do this yourself.  For sake of discussion, let's
94 consider adding support for the hypothetical TLS extension
95 @code{foobar}.
96
97 @enumerate
98
99 @item Add @code{configure} option like @code{--enable-foobar} or @code{--disable-foobar}.
100
101 This step is useful when the extension code is large and it might be desirable
102 to disable the extension under some circumstances. Otherwise it can be safely
103 skipped.
104
105 Whether to chose enable or disable depends on whether you intend to make the extension be
106 enabled by default.  Look at existing checks (i.e., SRP, authz) for
107 how to model the code.  For example:
108
109 @example
110 AC_MSG_CHECKING([whether to disable foobar support])
111 AC_ARG_ENABLE(foobar,
112         AS_HELP_STRING([--disable-foobar],
113                 [disable foobar support]),
114         ac_enable_foobar=no)
115 if test x$ac_enable_foobar != xno; then
116  AC_MSG_RESULT(no)
117  AC_DEFINE(ENABLE_FOOBAR, 1, [enable foobar])
118 else
119  ac_full=0
120  AC_MSG_RESULT(yes)
121 fi
122 AM_CONDITIONAL(ENABLE_FOOBAR, test "$ac_enable_foobar" != "no")
123 @end example
124
125 These lines should go in @code{lib/m4/hooks.m4}.
126
127 @item Add IANA extension value to @code{extensions_t} in @code{gnutls_int.h}.
128
129 A good name for the value would be GNUTLS_EXTENSION_FOOBAR.  Check
130 with @url{http://www.iana.org/assignments/tls-extensiontype-values}
131 for allocated values.  For experiments, you could pick a number but
132 remember that some consider it a bad idea to deploy such modified
133 version since it will lead to interoperability problems in the future
134 when the IANA allocates that number to someone else, or when the
135 foobar protocol is allocated another number.
136
137 @item Add an entry to @code{_gnutls_extensions} in @code{gnutls_extensions.c}.
138
139 A typical entry would be:
140
141 @example
142   int ret;
143
144   /* ...
145    */
146
147 #if ENABLE_FOOBAR
148
149   ret = _gnutls_ext_register (&foobar_ext);
150   if (ret != GNUTLS_E_SUCCESS)
151     return ret;
152 #endif
153 @end example
154
155 Most likely you'll need to add an @code{#include "ext_foobar.h"}, that
156 will contain something like
157 like:
158 @example
159   extension_entry_st foobar_ext = @{
160     .name = "FOOBAR",
161     .type = GNUTLS_EXTENSION_FOOBAR,
162     .parse_type = GNUTLS_EXT_TLS,
163     .recv_func = _foobar_recv_params,
164     .send_func = _foobar_send_params,
165     .pack_func = _foobar_pack,
166     .unpack_func = _foobar_unpack,
167     .deinit_func = NULL
168   @}
169 @end example
170
171 The GNUTLS_EXTENSION_FOOBAR is the integer value you added to
172 @code{gnutls_int.h} earlier.  In this structure you specify the
173 functions to read the extension from the hello message, the function
174 to send the reply to, and two more functions to pack and unpack from
175 stored session data (e.g. when resumming a session). The @code{deinit} function
176 will be called to deinitialize the extension's private parameters, if any.
177
178 Note that the conditional @code{ENABLE_FOOBAR} definition should only be 
179 used if step 1 with the @code{configure} options has taken place.
180
181 @item Add new files @code{ext_foobar.c} and @code{ext_foobar.h} that implement the extension.
182
183 The functions you are responsible to add are those mentioned in the
184 previous step.  As a starter, you could add this:
185
186 @example
187 int
188 _foobar_recv_params (gnutls_session_t session,
189                             const opaque * data,
190                             size_t data_size)
191 @{
192   return 0;
193 @}
194
195 int
196 _foobar_send_params (gnutls_session_t session,
197                             opaque * data,
198                             size_t _data_size)
199 @{
200   return 0;
201 @}
202
203 int
204 _foobar_pack (extension_priv_data_t epriv, gnutls_buffer_st * ps)
205 @{
206    /* Append the extension's internal state to buffer */
207    return 0;
208 @}
209
210 int
211 _foobar_unpack (gnutls_buffer_st * ps, extension_priv_data_t * epriv)
212 @{
213    /* Read the internal state from buffer */
214    return 0;
215 @}
216 @end example
217
218 The @code{_foobar_recv_params} function is responsible for
219 parsing incoming extension data (both in the client and server).
220
221 The @code{_foobar_send_params} function is responsible for
222 sending extension data (both in the client and server).
223
224 The @code{_foobar_pack} function is responsible for packing
225 internal extension data to save them in the session storage.
226
227 The @code{_foobar_unpack} function is responsible for
228 restoring session data from the session storage.
229
230 If you receive length fields that doesn't match, return
231 @code{GNUTLS_E_UNEXPECTED_PACKET_LENGTH}.  If you receive invalid
232 data, return @code{GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER}.  You can use
233 other error codes too.  Return 0 on success.
234
235 The function could store some information in the @code{session}
236 variable for later usage. That can be done using the functions 
237 @code{_gnutls_ext_set_session_data} and
238 @code{_gnutls_ext_get_session_data}. You can check simple examples
239 at @code{ext_max_record.c} and @code{ext_server_name.c} extensions.
240
241 Recall that both the client and server both send and receives
242 parameters, and your code most likely will need to do different things
243 depending on which mode it is in.  It may be useful to make this
244 distinction explicit in the code.  Thus, for example, a better
245 template than above would be:
246
247 @example
248 int
249 _gnutls_foobar_recv_params (gnutls_session_t session,
250                             const opaque * data,
251                             size_t data_size)
252 @{
253   if (session->security_parameters.entity == GNUTLS_CLIENT)
254     return foobar_recv_client (session, data, data_size);
255   else
256     return foobar_recv_server (session, data, data_size);
257 @}
258
259 int
260 _gnutls_foobar_send_params (gnutls_session_t session,
261                             opaque * data,
262                             size_t data_size)
263 @{
264   if (session->security_parameters.entity == GNUTLS_CLIENT)
265     return foobar_send_client (session, data, data_size);
266   else
267     return foobar_send_server (session, data, data_size);
268 @}
269 @end example
270
271 The functions used would be declared as @code{static} functions, of
272 the appropriate prototype, in the same file.
273
274 When adding the files, you'll need to add them to @code{Makefile.am}
275 as well, for example:
276
277 @example
278 if ENABLE_FOOBAR
279 COBJECTS += ext_foobar.c
280 HFILES += ext_foobar.h
281 endif
282 @end example
283
284 @item Add API functions to enable/disable the extension.
285
286 Normally the client will have one API to request use of the extension,
287 and setting some extension specific data.  The server will have one
288 API to let the library know that it is willing to accept the
289 extension, often this is implemented through a callback but it doesn't
290 have to.
291
292 The APIs need to be added to @code{includes/gnutls/gnutls.h} or
293 @code{includes/gnutls/extra.h} as appropriate.  It is recommended that
294 if you don't have a requirement to use the LGPLv2.1+ license for your
295 extension, that you place your work under the GPLv3+ license and thus
296 in the libgnutls-extra library.
297
298 You can implement the API function in the @code{ext_foobar.c} file, or
299 if that file ends up becoming rather larger, add a
300 @code{gnutls_foobar.c} file.
301
302 To make the API available in the shared library you need to add the
303 symbol in @code{lib/libgnutls.map} or
304 @code{libextra/libgnutls-extra.map} as appropriate, so that the symbol
305 is exported properly.
306
307 When writing GTK-DOC style documentation for your new APIs, don't
308 forget to add @code{Since:} tags to indicate the GnuTLS version the
309 API was introduced in.
310
311 @end enumerate
312
313 @node Certificate Handling
314 @section Certificate Handling
315 What is provided by the certificate handling functions
316 is summarized in the following diagram.
317
318 @image{gnutls-certificate-user-use-case,12cm}
319
320 @node Cryptographic Backend
321 @section Cryptographic Backend
322 Today most new processors, either for embedded or desktop systems
323 include either instructions  intended to speed up cryptographic operations,
324 or a co-processor with cryptographic capabilities. Taking advantage of 
325 those is a challenging task for every cryptographic  application or 
326 library. Unfortunately the cryptographic libraries that GnuTLS is based 
327 on take no advantage of these properties. For this reason GnuTLS handles 
328 this internally by following a layered approach to accessing
329 cryptographic operations as in the following figure. 
330
331 @image{gnutls-crypto-layers,12cm}
332
333 The TLS layer uses a cryptographic provider layer, that will in turn either 
334 use the default crypto provider - a crypto library, or use an external
335 crypto provider, if available.
336
337 @subsection Cryptographic Library layer
338 The Cryptographic Library layer, can  currently be used either with
339 libgcrypt or libnettle, each of one has its advantages and some 
340 disadvantages. Libgcrypt is a self-contained library, pretty broad 
341 in scope that supports many algorithms. In some processors like VIA, 
342 it will also use the available crypto instruction set hence providing
343 performance benefit comparing to plain software implementation.
344 Libnettle provides only software implementation
345 of the basic algorithms required in TLS, and is on average 30% faster
346 that libgcrypt on almost all algorithms. For
347 this reason libnettle is library used by default in GnuTLS.
348
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 reduce performance.
362
363 It is possible to override parts of crypto backend both at runtime and compile
364 time. Here we discuss the runtime possibility. The API
365 available for this functionality is in @code{gnutls/crypto.h} header
366 file.
367
368 @subsubsection Override specific algorithms
369 When an optimized implementation of a single algorithm is available,
370 say a hardware assisted version of @acronym{AES-CBC} then the
371 following functions can be used to register those algorithms.
372
373 @itemize
374
375 @item @ref{gnutls_crypto_single_cipher_register2}
376 To register a cipher algorithm.
377
378 @ref{gnutls_crypto_single_digest_register2}
379 To register a hash (digest) or MAC algorithm.
380
381 @end itemize
382
383 Those registration functions will only replace the specified algorithm
384 and leave the rest of subsystem intact.
385
386 @subsubsection Override parts of the backend
387 In some systems, such as embedded ones, it might be desirable to
388 override big parts of the cryptographic backend, or even all of
389 them. For this reason the following functions are provided.
390
391 @itemize
392
393 @item @ref{gnutls_crypto_cipher_register2}
394 To override the cryptographic algorithms backend.
395
396 @item @ref{gnutls_crypto_digest_register2}
397 To override the digest algorithms backend.
398
399 @item @ref{gnutls_crypto_rnd_register2}
400 To override the random number generator backend.
401
402 @item @ref{gnutls_crypto_bigint_register2}
403 To override the big number number operations backend.
404
405 @item @ref{gnutls_crypto_pk_register2}
406 To override the public key encryption backend. This is tight to the
407 big number operations so either both of them should be updated or care
408 must be taken to use the same format.
409
410 @end itemize
411
412 If all of them are used then GnuTLS will no longer use libgcrypt.