certtool is able to set certificate policies via a template
[gnutls.git] / lib / verify-tofu.c
blob3592395803f1d6e11afa2f31ff8201f9d059ff42
1 /*
2 * Copyright (C) 2012 Free Software Foundation, Inc.
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GnuTLS.
8 * The GnuTLS is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 3 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>
23 #include <gnutls_int.h>
24 #include <gnutls_errors.h>
25 #include <libtasn1.h>
26 #include <gnutls_global.h>
27 #include <gnutls_num.h> /* MAX */
28 #include <gnutls_sig.h>
29 #include <gnutls_str.h>
30 #include <gnutls_datum.h>
31 #include "x509_int.h"
32 #include <common.h>
33 #include <base64.h>
34 #include <gnutls/abstract.h>
35 #include <system.h>
36 #include <locks.h>
38 struct gnutls_tdb_int {
39 gnutls_tdb_store_func store;
40 gnutls_tdb_store_commitment_func cstore;
41 gnutls_tdb_verify_func verify;
44 static int raw_pubkey_to_base64(const gnutls_datum_t* raw, gnutls_datum_t * b64);
45 static int x509_crt_to_raw_pubkey(const gnutls_datum_t * cert, gnutls_datum_t *rpubkey);
46 static int pgp_crt_to_raw_pubkey(const gnutls_datum_t * cert, gnutls_datum_t *rpubkey);
47 static int verify_pubkey(const char* file,
48 const char* host, const char* service,
49 const gnutls_datum_t* skey);
51 static
52 int store_commitment(const char* db_name, const char* host,
53 const char* service, time_t expiration,
54 gnutls_digest_algorithm_t hash_algo,
55 const gnutls_datum_t* hash);
56 static
57 int store_pubkey(const char* db_name, const char* host,
58 const char* service, time_t expiration, const gnutls_datum_t* pubkey);
60 static int find_config_file(char* file, size_t max_size);
61 #define MAX_FILENAME 512
63 void *_gnutls_file_mutex;
65 struct gnutls_tdb_int default_tdb = {
66 store_pubkey,
67 store_commitment,
68 verify_pubkey
72 /**
73 * gnutls_verify_stored_pubkey:
74 * @db_name: A file specifying the stored keys (use NULL for the default)
75 * @tdb: A storage structure or NULL to use the default
76 * @host: The peer's name
77 * @service: non-NULL if this key is specific to a service (e.g. http)
78 * @cert_type: The type of the certificate
79 * @cert: The raw (der) data of the certificate
80 * @flags: should be 0.
82 * This function will try to verify the provided certificate using
83 * a list of stored public keys. The @service field if non-NULL should
84 * be a port number.
86 * The @retrieve variable if non-null specifies a custom backend for
87 * the retrieval of entries. If it is NULL then the
88 * default file backend will be used. In POSIX-like systems the
89 * file backend uses the $HOME/.gnutls/known_hosts file.
91 * Note that if the custom storage backend is provided the
92 * retrieval function should return %GNUTLS_E_CERTIFICATE_KEY_MISMATCH
93 * if the host/service pair is found but key doesn't match,
94 * %GNUTLS_E_NO_CERTIFICATE_FOUND if no such host/service with
95 * the given key is found, and 0 if it was found. The storage
96 * function should return 0 on success.
98 * Returns: If no associated public key is found
99 * then %GNUTLS_E_NO_CERTIFICATE_FOUND will be returned. If a key
100 * is found but does not match %GNUTLS_E_CERTIFICATE_KEY_MISMATCH
101 * is returned. On success, %GNUTLS_E_SUCCESS (0) is returned,
102 * or a negative error value on other errors.
104 * Since: 3.0
107 gnutls_verify_stored_pubkey(const char* db_name,
108 gnutls_tdb_t tdb,
109 const char* host,
110 const char* service,
111 gnutls_certificate_type_t cert_type,
112 const gnutls_datum_t * cert, unsigned int flags)
114 gnutls_datum_t pubkey = { NULL, 0 };
115 int ret;
116 char local_file[MAX_FILENAME];
118 if (cert_type != GNUTLS_CRT_X509 && cert_type != GNUTLS_CRT_OPENPGP)
119 return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE);
121 if (db_name == NULL && tdb == NULL)
123 ret = find_config_file(local_file, sizeof(local_file));
124 if (ret < 0)
125 return gnutls_assert_val(ret);
126 db_name = local_file;
129 if (tdb == NULL)
130 tdb = &default_tdb;
132 if (cert_type == GNUTLS_CRT_X509)
133 ret = x509_crt_to_raw_pubkey(cert, &pubkey);
134 else
135 ret = pgp_crt_to_raw_pubkey(cert, &pubkey);
137 if (ret < 0)
139 gnutls_assert();
140 goto cleanup;
143 ret = tdb->verify(db_name, host, service, &pubkey);
144 if (ret < 0 && ret != GNUTLS_E_CERTIFICATE_KEY_MISMATCH)
145 ret = gnutls_assert_val(GNUTLS_E_NO_CERTIFICATE_FOUND);
147 cleanup:
148 gnutls_free(pubkey.data);
149 return ret;
152 static int parse_commitment_line(char* line,
153 const char* host, size_t host_len,
154 const char* service, size_t service_len,
155 time_t now,
156 const gnutls_datum_t *skey)
158 char* p, *kp;
159 char* savep = NULL;
160 size_t kp_len, phash_size;
161 time_t expiration;
162 int ret;
163 gnutls_digest_algorithm_t hash_algo;
164 uint8_t phash[MAX_HASH_SIZE];
165 uint8_t hphash[MAX_HASH_SIZE*2+1];
167 /* read host */
168 p = strtok_r(line, "|", &savep);
169 if (p == NULL)
170 return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
172 if (p[0] != '*' && strcmp(p, host) != 0)
173 return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
175 /* read service */
176 p = strtok_r(NULL, "|", &savep);
177 if (p == NULL)
178 return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
180 if (p[0] != '*' && strcmp(p, service) != 0)
181 return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
183 /* read expiration */
184 p = strtok_r(NULL, "|", &savep);
185 if (p == NULL)
186 return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
188 expiration = (time_t)atol(p);
189 if (expiration > 0 && now > expiration)
190 return gnutls_assert_val(GNUTLS_E_EXPIRED);
192 /* read hash algorithm */
193 p = strtok_r(NULL, "|", &savep);
194 if (p == NULL)
195 return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
197 hash_algo = (time_t)atol(p);
198 if (_gnutls_digest_get_name(hash_algo) == NULL)
199 return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
201 /* read hash */
202 kp = strtok_r(NULL, "|", &savep);
203 if (kp == NULL)
204 return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
206 p = strpbrk(kp, "\n \r\t|");
207 if (p != NULL) *p = 0;
209 /* hash and hex encode */
210 ret = _gnutls_hash_fast (hash_algo, skey->data, skey->size, phash);
211 if (ret < 0)
212 return gnutls_assert_val(ret);
214 phash_size = _gnutls_hash_get_algo_len(hash_algo);
216 p = _gnutls_bin2hex (phash, phash_size,(void*) hphash,
217 sizeof(hphash), NULL);
218 if (p == NULL)
219 return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
221 kp_len = strlen(kp);
222 if (kp_len != phash_size*2)
223 return gnutls_assert_val(GNUTLS_E_CERTIFICATE_KEY_MISMATCH);
225 if (memcmp(kp, hphash, kp_len) != 0)
226 return gnutls_assert_val(GNUTLS_E_CERTIFICATE_KEY_MISMATCH);
228 /* key found and matches */
229 return 0;
233 static int parse_line(char* line,
234 const char* host, size_t host_len,
235 const char* service, size_t service_len,
236 time_t now,
237 const gnutls_datum_t *rawkey,
238 const gnutls_datum_t *b64key)
240 char* p, *kp;
241 char* savep = NULL;
242 size_t kp_len;
243 time_t expiration;
245 /* read version */
246 p = strtok_r(line, "|", &savep);
247 if (p == NULL)
248 return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
250 if (strncmp(p, "c0", 2) == 0)
251 return parse_commitment_line(p+3, host, host_len, service, service_len, now, rawkey);
253 if (strncmp(p, "g0", 2) != 0)
254 return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
256 /* read host */
257 p = strtok_r(NULL, "|", &savep);
258 if (p == NULL)
259 return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
261 if (p[0] != '*' && strcmp(p, host) != 0)
262 return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
264 /* read service */
265 p = strtok_r(NULL, "|", &savep);
266 if (p == NULL)
267 return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
269 if (p[0] != '*' && strcmp(p, service) != 0)
270 return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
272 /* read expiration */
273 p = strtok_r(NULL, "|", &savep);
274 if (p == NULL)
275 return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
277 expiration = (time_t)atol(p);
278 if (expiration > 0 && now > expiration)
279 return gnutls_assert_val(GNUTLS_E_EXPIRED);
281 /* read key */
282 kp = strtok_r(NULL, "|", &savep);
283 if (kp == NULL)
284 return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
286 p = strpbrk(kp, "\n \r\t|");
287 if (p != NULL) *p = 0;
289 kp_len = strlen(kp);
290 if (kp_len != b64key->size)
291 return gnutls_assert_val(GNUTLS_E_CERTIFICATE_KEY_MISMATCH);
293 if (memcmp(kp, b64key->data, b64key->size) != 0)
294 return gnutls_assert_val(GNUTLS_E_CERTIFICATE_KEY_MISMATCH);
296 /* key found and matches */
297 return 0;
300 /* Returns the base64 key if found
302 static int verify_pubkey(const char* file,
303 const char* host, const char* service,
304 const gnutls_datum_t* pubkey)
306 FILE* fd;
307 char* line = NULL;
308 size_t line_size = 0;
309 int ret, l2, mismatch = 0;
310 size_t host_len = 0, service_len = 0;
311 time_t now = gnutls_time(0);
312 gnutls_datum_t b64key = { NULL, 0 };
314 ret = raw_pubkey_to_base64(pubkey, &b64key);
315 if (ret < 0)
316 return gnutls_assert_val(ret);
318 if (host != NULL) host_len = strlen(host);
319 if (service != NULL) service_len = strlen(service);
321 fd = fopen(file, "rb");
322 if (fd == NULL)
324 ret = gnutls_assert_val(GNUTLS_E_FILE_ERROR);
325 goto cleanup;
330 l2 = getline(&line, &line_size, fd);
331 if (l2 > 0)
333 ret = parse_line(line, host, host_len, service, service_len, now, pubkey, &b64key);
334 if (ret == 0) /* found */
336 goto cleanup;
338 else if (ret == GNUTLS_E_CERTIFICATE_KEY_MISMATCH)
339 mismatch = 1;
342 while(l2 >= 0);
344 if (mismatch)
345 ret = GNUTLS_E_CERTIFICATE_KEY_MISMATCH;
346 else
347 ret = GNUTLS_E_NO_CERTIFICATE_FOUND;
349 cleanup:
350 free(line);
351 if (fd != NULL)
352 fclose(fd);
353 gnutls_free(b64key.data);
355 return ret;
358 static int raw_pubkey_to_base64(const gnutls_datum_t* raw, gnutls_datum_t * b64)
360 int ret;
361 char* out;
363 ret = base64_encode_alloc((void*)raw->data, raw->size, &out);
364 if (ret == 0)
365 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
367 b64->data = (void*)out;
368 b64->size = ret;
370 return 0;
373 static int x509_crt_to_raw_pubkey(const gnutls_datum_t * cert, gnutls_datum_t *rpubkey)
375 gnutls_x509_crt_t crt = NULL;
376 gnutls_pubkey_t pubkey = NULL;
377 size_t size;
378 int ret;
380 ret = gnutls_x509_crt_init(&crt);
381 if (ret < 0)
382 return gnutls_assert_val(ret);
384 ret = gnutls_pubkey_init(&pubkey);
385 if (ret < 0)
387 gnutls_assert();
388 goto cleanup;
391 ret = gnutls_x509_crt_import(crt, cert, GNUTLS_X509_FMT_DER);
392 if (ret < 0)
394 gnutls_assert();
395 goto cleanup;
398 ret = gnutls_pubkey_import_x509 (pubkey, crt, 0);
399 if (ret < 0)
401 gnutls_assert();
402 goto cleanup;
405 size = 0;
406 ret = gnutls_pubkey_export(pubkey, GNUTLS_X509_FMT_DER, NULL, &size);
407 if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
409 gnutls_assert();
410 goto cleanup;
413 rpubkey->data = gnutls_malloc(size);
414 if (rpubkey->data == NULL)
415 if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
417 ret = GNUTLS_E_MEMORY_ERROR;
418 gnutls_assert();
419 goto cleanup;
422 ret = gnutls_pubkey_export(pubkey, GNUTLS_X509_FMT_DER, rpubkey->data, &size);
423 if (ret < 0)
425 gnutls_free(rpubkey->data);
426 gnutls_assert();
427 goto cleanup;
430 rpubkey->size = size;
431 ret = 0;
433 cleanup:
434 gnutls_x509_crt_deinit(crt);
435 gnutls_pubkey_deinit(pubkey);
437 return ret;
440 static int pgp_crt_to_raw_pubkey(const gnutls_datum_t * cert, gnutls_datum_t *rpubkey)
442 #ifdef ENABLE_OPENPGP
443 gnutls_openpgp_crt_t crt = NULL;
444 gnutls_pubkey_t pubkey = NULL;
445 size_t size;
446 int ret;
448 ret = gnutls_openpgp_crt_init(&crt);
449 if (ret < 0)
450 return gnutls_assert_val(ret);
452 ret = gnutls_pubkey_init(&pubkey);
453 if (ret < 0)
455 gnutls_assert();
456 goto cleanup;
459 ret = gnutls_openpgp_crt_import(crt, cert, GNUTLS_OPENPGP_FMT_RAW);
460 if (ret < 0)
462 gnutls_assert();
463 goto cleanup;
466 ret = gnutls_pubkey_import_openpgp (pubkey, crt, 0);
467 if (ret < 0)
469 gnutls_assert();
470 goto cleanup;
473 size = 0;
474 ret = gnutls_pubkey_export(pubkey, GNUTLS_X509_FMT_DER, NULL, &size);
475 if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
477 gnutls_assert();
478 goto cleanup;
481 rpubkey->data = gnutls_malloc(size);
482 if (rpubkey->data == NULL)
483 if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
485 ret = GNUTLS_E_MEMORY_ERROR;
486 gnutls_assert();
487 goto cleanup;
490 ret = gnutls_pubkey_export(pubkey, GNUTLS_X509_FMT_DER, rpubkey->data, &size);
491 if (ret < 0)
493 gnutls_free(rpubkey->data);
494 gnutls_assert();
495 goto cleanup;
498 rpubkey->size = size;
499 ret = 0;
501 cleanup:
502 gnutls_openpgp_crt_deinit(crt);
503 gnutls_pubkey_deinit(pubkey);
505 return ret;
506 #else
507 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
508 #endif
511 static
512 int store_pubkey(const char* db_name, const char* host,
513 const char* service, time_t expiration,
514 const gnutls_datum_t* pubkey)
516 FILE* fd = NULL;
517 gnutls_datum_t b64key = { NULL, 0 };
518 int ret;
520 ret = gnutls_mutex_lock(&_gnutls_file_mutex);
521 if (ret != 0)
522 return gnutls_assert_val(GNUTLS_E_LOCKING_ERROR);
524 ret = raw_pubkey_to_base64(pubkey, &b64key);
525 if (ret < 0)
527 gnutls_assert();
528 goto cleanup;
531 fd = fopen(db_name, "ab+");
532 if (fd == NULL)
534 ret = gnutls_assert_val(GNUTLS_E_FILE_ERROR);
535 goto cleanup;
538 if (service == NULL) service = "*";
539 if (host == NULL) host = "*";
541 fprintf(fd, "|g0|%s|%s|%lu|%.*s\n", host, service, (unsigned long)expiration,
542 b64key.size, b64key.data);
544 ret = 0;
546 cleanup:
547 if (fd != NULL)
548 fclose(fd);
550 gnutls_mutex_unlock(&_gnutls_file_mutex);
551 gnutls_free(b64key.data);
553 return ret;
556 static
557 int store_commitment(const char* db_name, const char* host,
558 const char* service, time_t expiration,
559 gnutls_digest_algorithm_t hash_algo,
560 const gnutls_datum_t* hash)
562 FILE* fd;
563 char buffer[MAX_HASH_SIZE*2+1];
565 fd = fopen(db_name, "ab+");
566 if (fd == NULL)
567 return gnutls_assert_val(GNUTLS_E_FILE_ERROR);
569 if (service == NULL) service = "*";
570 if (host == NULL) host = "*";
572 fprintf(fd, "|c0|%s|%s|%lu|%u|%s\n", host, service, (unsigned long)expiration,
573 (unsigned)hash_algo, _gnutls_bin2hex(hash->data, hash->size, buffer, sizeof(buffer), NULL));
575 fclose(fd);
577 return 0;
581 * gnutls_store_pubkey:
582 * @db_name: A file specifying the stored keys (use NULL for the default)
583 * @tdb: A storage structure or NULL to use the default
584 * @host: The peer's name
585 * @service: non-NULL if this key is specific to a service (e.g. http)
586 * @cert_type: The type of the certificate
587 * @cert: The data of the certificate
588 * @expiration: The expiration time (use 0 to disable expiration)
589 * @flags: should be 0.
591 * This function will store the provided certificate to
592 * the list of stored public keys. The key will be considered valid until
593 * the provided expiration time.
595 * The @store variable if non-null specifies a custom backend for
596 * the storage of entries. If it is NULL then the
597 * default file backend will be used.
599 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
600 * negative error value.
602 * Since: 3.0
605 gnutls_store_pubkey(const char* db_name,
606 gnutls_tdb_t tdb,
607 const char* host,
608 const char* service,
609 gnutls_certificate_type_t cert_type,
610 const gnutls_datum_t * cert,
611 time_t expiration,
612 unsigned int flags)
614 FILE* fd = NULL;
615 gnutls_datum_t pubkey = { NULL, 0 };
616 int ret;
617 char local_file[MAX_FILENAME];
619 if (cert_type != GNUTLS_CRT_X509 && cert_type != GNUTLS_CRT_OPENPGP)
620 return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE);
622 if (db_name == NULL && tdb == NULL)
624 ret = _gnutls_find_config_path(local_file, sizeof(local_file));
625 if (ret < 0)
626 return gnutls_assert_val(ret);
628 _gnutls_debug_log("Configuration path: %s\n", local_file);
629 mkdir(local_file, 0700);
631 ret = find_config_file(local_file, sizeof(local_file));
632 if (ret < 0)
633 return gnutls_assert_val(ret);
634 db_name = local_file;
637 if (tdb == NULL)
638 tdb = &default_tdb;
640 if (cert_type == GNUTLS_CRT_X509)
641 ret = x509_crt_to_raw_pubkey(cert, &pubkey);
642 else
643 ret = pgp_crt_to_raw_pubkey(cert, &pubkey);
644 if (ret < 0)
646 gnutls_assert();
647 goto cleanup;
650 _gnutls_debug_log("Configuration file: %s\n", db_name);
652 tdb->store(db_name, host, service, expiration, &pubkey);
654 ret = 0;
656 cleanup:
657 gnutls_free(pubkey.data);
658 if (fd != NULL) fclose(fd);
660 return ret;
664 * gnutls_store_commitment:
665 * @db_name: A file specifying the stored keys (use NULL for the default)
666 * @tdb: A storage structure or NULL to use the default
667 * @host: The peer's name
668 * @service: non-NULL if this key is specific to a service (e.g. http)
669 * @hash_algo: The hash algorithm type
670 * @hash: The raw hash
671 * @expiration: The expiration time (use 0 to disable expiration)
672 * @flags: should be 0.
674 * This function will store the provided hash commitment to
675 * the list of stored public keys. The key with the given
676 * hash will be considered valid until the provided expiration time.
678 * The @store variable if non-null specifies a custom backend for
679 * the storage of entries. If it is NULL then the
680 * default file backend will be used.
682 * Note that this function is not thread safe with the default backend.
684 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
685 * negative error value.
687 * Since: 3.0
690 gnutls_store_commitment(const char* db_name,
691 gnutls_tdb_t tdb,
692 const char* host,
693 const char* service,
694 gnutls_digest_algorithm_t hash_algo,
695 const gnutls_datum_t* hash,
696 time_t expiration,
697 unsigned int flags)
699 FILE* fd = NULL;
700 int ret;
701 char local_file[MAX_FILENAME];
703 if (_gnutls_digest_is_secure(hash_algo) == 0)
704 return gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
706 if (_gnutls_hash_get_algo_len(hash_algo) != hash->size)
707 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
709 if (db_name == NULL && tdb == NULL)
711 ret = _gnutls_find_config_path(local_file, sizeof(local_file));
712 if (ret < 0)
713 return gnutls_assert_val(ret);
715 _gnutls_debug_log("Configuration path: %s\n", local_file);
716 mkdir(local_file, 0700);
718 ret = find_config_file(local_file, sizeof(local_file));
719 if (ret < 0)
720 return gnutls_assert_val(ret);
721 db_name = local_file;
724 if (tdb == NULL)
725 tdb = &default_tdb;
727 _gnutls_debug_log("Configuration file: %s\n", db_name);
729 tdb->cstore(db_name, host, service, expiration, hash_algo, hash);
731 ret = 0;
733 if (fd != NULL) fclose(fd);
735 return ret;
738 #define CONFIG_FILE "known_hosts"
740 static int find_config_file(char* file, size_t max_size)
742 char path[MAX_FILENAME];
743 int ret;
745 ret = _gnutls_find_config_path(path, sizeof(path));
746 if (ret < 0)
747 return gnutls_assert_val(ret);
749 if (path[0] == 0)
750 snprintf(file, max_size, "%s", CONFIG_FILE);
751 else
752 snprintf(file, max_size, "%s/%s", path, CONFIG_FILE);
754 return 0;
758 * gnutls_tdb_init:
759 * @tdb: The structure to be initialized
761 * This function will initialize a public key trust storage structure.
763 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
764 * negative error value.
766 int gnutls_tdb_init(gnutls_tdb_t* tdb)
768 *tdb = gnutls_calloc (1, sizeof (struct gnutls_tdb_int));
770 if (!*tdb)
771 return GNUTLS_E_MEMORY_ERROR;
773 return 0;
777 * gnutls_set_store_func:
778 * @tdb: The trust storage
779 * @store: The storage function
781 * This function will associate a storage function with the
782 * trust storage structure. The function is of the following form.
784 * gnutls_tdb_store_func(const char* db_name, const char* host,
785 * const char* service, time_t expiration,
786 * const gnutls_datum_t* pubkey);
789 void gnutls_tdb_set_store_func(gnutls_tdb_t tdb, gnutls_tdb_store_func store)
791 tdb->store = store;
795 * gnutls_set_store_commitment_func:
796 * @tdb: The trust storage
797 * @cstore: The commitment storage function
799 * This function will associate a commitment (hash) storage function with the
800 * trust storage structure. The function is of the following form.
802 * gnutls_tdb_store_commitment_func(const char* db_name, const char* host,
803 * const char* service, time_t expiration,
804 * gnutls_digest_algorithm_t, const gnutls_datum_t* hash);
807 void gnutls_tdb_set_store_commitment_func(gnutls_tdb_t tdb,
808 gnutls_tdb_store_commitment_func cstore)
810 tdb->cstore = cstore;
814 * gnutls_set_verify_func:
815 * @tdb: The trust storage
816 * @verify: The verification function
818 * This function will associate a retrieval function with the
819 * trust storage structure. The function is of the following form.
821 * gnutls_tdb_verify_func(const char* db_name, const char* host,
822 * const char* service, const gnutls_datum_t* pubkey);
825 void gnutls_tdb_set_verify_func(gnutls_tdb_t tdb, gnutls_tdb_verify_func verify)
827 tdb->verify = verify;
831 * gnutls_tdb_deinit:
832 * @tdb: The structure to be deinitialized
834 * This function will deinitialize a public key trust storage structure.
836 void gnutls_tdb_deinit(gnutls_tdb_t tdb)
838 gnutls_free(tdb);