Tizen 2.0 Release
[external/libgnutls26.git] / lib / gnutls_global.c
1 /*
2  * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009, 2010
3  * Free Software Foundation, Inc.
4  *
5  * Author: Nikos Mavrogiannopoulos
6  *
7  * This file is part of GnuTLS.
8  *
9  * The GnuTLS is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License
11  * as published by the Free Software Foundation; either version 2.1 of
12  * the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
22  * USA
23  *
24  */
25
26 #include <gnutls_int.h>
27 #include <gnutls_errors.h>
28 #include <libtasn1.h>
29 #include <gnutls_dh.h>
30 #include <random.h>
31 #include <gnutls/pkcs11.h>
32
33 #include <gnutls_extensions.h>  /* for _gnutls_ext_init */
34 #include <gnutls_cryptodev.h>
35 #include <locks.h>
36 #include <system.h>
37
38 #include "sockets.h"
39 #include "gettext.h"
40
41 /* Minimum library versions we accept. */
42 #define GNUTLS_MIN_LIBTASN1_VERSION "0.3.4"
43
44 /* created by asn1c */
45 extern const ASN1_ARRAY_TYPE gnutls_asn1_tab[];
46 extern const ASN1_ARRAY_TYPE pkix_asn1_tab[];
47
48 ASN1_TYPE _gnutls_pkix1_asn;
49 ASN1_TYPE _gnutls_gnutls_asn;
50
51 gnutls_log_func _gnutls_log_func;
52 int _gnutls_log_level = 0;      /* default log level */
53
54 /**
55  * gnutls_global_set_log_function:
56  * @log_func: it's a log function
57  *
58  * This is the function where you set the logging function gnutls is
59  * going to use.  This function only accepts a character array.
60  * Normally you may not use this function since it is only used for
61  * debugging purposes.
62  *
63  * gnutls_log_func is of the form,
64  * void (*gnutls_log_func)( int level, const char*);
65  **/
66 void
67 gnutls_global_set_log_function (gnutls_log_func log_func)
68 {
69   _gnutls_log_func = log_func;
70 }
71
72 /**
73  * gnutls_global_set_time_function:
74  * @time_func: it's the system time function
75  *
76  * This is the function where you can override the default system
77  * time function.
78  *
79  * gnutls_time_func is of the form,
80  * time_t (*gnutls_time_func)( time*);
81  **/
82 void
83 gnutls_global_set_time_function (gnutls_time_func time_func)
84 {
85   gnutls_time = time_func;
86 }
87
88 /**
89  * gnutls_global_set_log_level:
90  * @level: it's an integer from 0 to 9.
91  *
92  * This is the function that allows you to set the log level.  The
93  * level is an integer between 0 and 9.  Higher values mean more
94  * verbosity. The default value is 0.  Larger values should only be
95  * used with care, since they may reveal sensitive information.
96  *
97  * Use a log level over 10 to enable all debugging options.
98  **/
99 void
100 gnutls_global_set_log_level (int level)
101 {
102   _gnutls_log_level = level;
103 }
104
105 /**
106  * gnutls_global_set_mem_functions:
107  * @alloc_func: it's the default memory allocation function. Like malloc().
108  * @secure_alloc_func: This is the memory allocation function that will be used for sensitive data.
109  * @is_secure_func: a function that returns 0 if the memory given is not secure. May be NULL.
110  * @realloc_func: A realloc function
111  * @free_func: The function that frees allocated data. Must accept a NULL pointer.
112  *
113  * This is the function were you set the memory allocation functions
114  * gnutls is going to use. By default the libc's allocation functions
115  * (malloc(), free()), are used by gnutls, to allocate both sensitive
116  * and not sensitive data.  This function is provided to set the
117  * memory allocation functions to something other than the defaults
118  *
119  * This function must be called before gnutls_global_init() is called.
120  * This function is not thread safe.
121  **/
122 void
123 gnutls_global_set_mem_functions (gnutls_alloc_function alloc_func,
124                                  gnutls_alloc_function secure_alloc_func,
125                                  gnutls_is_secure_function is_secure_func,
126                                  gnutls_realloc_function realloc_func,
127                                  gnutls_free_function free_func)
128 {
129   gnutls_secure_malloc = secure_alloc_func;
130   gnutls_malloc = alloc_func;
131   gnutls_realloc = realloc_func;
132   gnutls_free = free_func;
133
134   if (is_secure_func != NULL)
135     _gnutls_is_secure_memory = is_secure_func;
136   else
137     _gnutls_is_secure_memory = _gnutls_is_secure_mem_null;
138
139   /* if using the libc's default malloc
140    * use libc's calloc as well.
141    */
142   if (gnutls_malloc == malloc)
143     {
144       gnutls_calloc = calloc;
145     }
146   else
147     {                           /* use the included ones */
148       gnutls_calloc = _gnutls_calloc;
149     }
150   gnutls_strdup = _gnutls_strdup;
151
152 }
153
154 static int _gnutls_init = 0;
155
156
157 /**
158  * gnutls_global_init:
159  *
160  * This function initializes the global data to defaults.  Every
161  * gnutls application has a global data which holds common parameters
162  * shared by gnutls session structures.  You should call
163  * gnutls_global_deinit() when gnutls usage is no longer needed
164  *
165  * Note that this function will also initialize the underlying crypto
166  * backend, if it has not been initialized before.  
167  *
168  * This function increment a global counter, so that
169  * gnutls_global_deinit() only releases resources when it has been
170  * called as many times as gnutls_global_init().  This is useful when
171  * GnuTLS is used by more than one library in an application.  This
172  * function can be called many times, but will only do something the
173  * first time.
174  *
175  * Note!  This function is not thread safe.  If two threads call this
176  * function simultaneously, they can cause a race between checking
177  * the global counter and incrementing it, causing both threads to
178  * execute the library initialization code.  That would lead to a
179  * memory leak.  To handle this, your application could invoke this
180  * function after aquiring a thread mutex.  To ignore the potential
181  * memory leak is also an option.
182  *
183  * Returns: On success, %GNUTLS_E_SUCCESS (zero) is returned,
184  *   otherwise an error code is returned.
185  **/
186 int
187 gnutls_global_init (void)
188 {
189   int result = 0;
190   int res;
191
192   if (_gnutls_init++)
193     goto out;
194
195   if (gl_sockets_startup (SOCKETS_1_1))
196     return GNUTLS_E_LIBRARY_VERSION_MISMATCH;
197
198   bindtextdomain (PACKAGE, LOCALEDIR);
199
200   res = gnutls_crypto_init ();
201   if (res != 0)
202     {
203       gnutls_assert ();
204       return GNUTLS_E_CRYPTO_INIT_FAILED;
205     }
206
207   /* initialize ASN.1 parser
208    * This should not deal with files in the final
209    * version.
210    */
211   if (asn1_check_version (GNUTLS_MIN_LIBTASN1_VERSION) == NULL)
212     {
213       gnutls_assert ();
214       _gnutls_debug_log ("Checking for libtasn1 failed: %s < %s\n",
215                          asn1_check_version (NULL),
216                          GNUTLS_MIN_LIBTASN1_VERSION);
217       return GNUTLS_E_INCOMPATIBLE_LIBTASN1_LIBRARY;
218     }
219
220   res = asn1_array2tree (pkix_asn1_tab, &_gnutls_pkix1_asn, NULL);
221   if (res != ASN1_SUCCESS)
222     {
223       result = _gnutls_asn2err (res);
224       goto out;
225     }
226
227   res = asn1_array2tree (gnutls_asn1_tab, &_gnutls_gnutls_asn, NULL);
228   if (res != ASN1_SUCCESS)
229     {
230       asn1_delete_structure (&_gnutls_pkix1_asn);
231       result = _gnutls_asn2err (res);
232       goto out;
233     }
234
235   /* Initialize the random generator */
236   result = _gnutls_rnd_init ();
237   if (result < 0)
238     {
239       gnutls_assert ();
240       goto out;
241     }
242
243   /* Initialize the default TLS extensions */
244   result = _gnutls_ext_init ();
245   if (result < 0)
246     {
247       gnutls_assert ();
248       goto out;
249     }
250
251 #ifdef ENABLE_PKCS11
252   gnutls_pkcs11_init (GNUTLS_PKCS11_FLAG_AUTO, NULL);
253 #endif
254
255   _gnutls_cryptodev_init ();
256
257 out:
258   return result;
259 }
260
261 /**
262  * gnutls_global_deinit:
263  *
264  * This function deinitializes the global data, that were initialized
265  * using gnutls_global_init().
266  *
267  * Note!  This function is not thread safe.  See the discussion for
268  * gnutls_global_init() for more information.
269  **/
270 void
271 gnutls_global_deinit (void)
272 {
273   if (_gnutls_init == 1)
274     {
275       gl_sockets_cleanup ();
276       _gnutls_rnd_deinit ();
277       _gnutls_ext_deinit ();
278       asn1_delete_structure (&_gnutls_gnutls_asn);
279       asn1_delete_structure (&_gnutls_pkix1_asn);
280       _gnutls_crypto_deregister ();
281       _gnutls_cryptodev_deinit ();
282 #ifdef ENABLE_PKCS11
283       gnutls_pkcs11_deinit ();
284 #endif
285     }
286   _gnutls_init--;
287 }
288
289 /* These functions should be elsewere. Kept here for
290  * historical reasons.
291  */
292
293
294 /**
295  * gnutls_check_version:
296  * @req_version: version string to compare with, or %NULL.
297  *
298  * Check GnuTLS Library version.
299  *
300  * See %GNUTLS_VERSION for a suitable @req_version string.
301  *
302  * Return value: Check that the version of the library is at
303  *   minimum the one given as a string in @req_version and return the
304  *   actual version string of the library; return %NULL if the
305  *   condition is not met.  If %NULL is passed to this function no
306  *   check is done and only the version string is returned.
307   **/
308 const char *
309 gnutls_check_version (const char *req_version)
310 {
311   if (!req_version || strverscmp (req_version, VERSION) <= 0)
312     return VERSION;
313
314   return NULL;
315 }