If a client hello is received immediately after a completed handshake delete the...
[gnutls.git] / lib / verify-tofu.c
blob7304cb76c8b083129badab910b8dca91b12e7a2f
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 <hash.h>
32 #include "x509_int.h"
33 #include <common.h>
34 #include <base64.h>
35 #include <gnutls/abstract.h>
36 #include <system.h>
37 #include <locks.h>
39 struct gnutls_tdb_int {
40 gnutls_tdb_store_func store;
41 gnutls_tdb_store_commitment_func cstore;
42 gnutls_tdb_verify_func verify;
45 static int raw_pubkey_to_base64(const gnutls_datum_t* raw, gnutls_datum_t * b64);
46 static int x509_crt_to_raw_pubkey(const gnutls_datum_t * cert, gnutls_datum_t *rpubkey);
47 static int pgp_crt_to_raw_pubkey(const gnutls_datum_t * cert, gnutls_datum_t *rpubkey);
48 static int verify_pubkey(const char* file,
49 const char* host, const char* service,
50 const gnutls_datum_t* skey);
52 static
53 int store_commitment(const char* db_name, const char* host,
54 const char* service, time_t expiration,
55 gnutls_digest_algorithm_t hash_algo,
56 const gnutls_datum_t* hash);
57 static
58 int store_pubkey(const char* db_name, const char* host,
59 const char* service, time_t expiration, const gnutls_datum_t* pubkey);
61 static int find_config_file(char* file, size_t max_size);
62 #define MAX_FILENAME 512
64 void *_gnutls_file_mutex;
66 struct gnutls_tdb_int default_tdb = {
67 store_pubkey,
68 store_commitment,
69 verify_pubkey
73 /**
74 * gnutls_verify_stored_pubkey:
75 * @db_name: A file specifying the stored keys (use NULL for the default)
76 * @tdb: A storage structure or NULL to use the default
77 * @host: The peer's name
78 * @service: non-NULL if this key is specific to a service (e.g. http)
79 * @cert_type: The type of the certificate
80 * @cert: The raw (der) data of the certificate
81 * @flags: should be 0.
83 * This function will try to verify the provided certificate using
84 * a list of stored public keys. The @service field if non-NULL should
85 * be a port number.
87 * The @retrieve variable if non-null specifies a custom backend for
88 * the retrieval of entries. If it is NULL then the
89 * default file backend will be used. In POSIX-like systems the
90 * file backend uses the $HOME/.gnutls/known_hosts file.
92 * Note that if the custom storage backend is provided the
93 * retrieval function should return %GNUTLS_E_CERTIFICATE_KEY_MISMATCH
94 * if the host/service pair is found but key doesn't match,
95 * %GNUTLS_E_NO_CERTIFICATE_FOUND if no such host/service with
96 * the given key is found, and 0 if it was found. The storage
97 * function should return 0 on success.
99 * Returns: If no associated public key is found
100 * then %GNUTLS_E_NO_CERTIFICATE_FOUND will be returned. If a key
101 * is found but does not match %GNUTLS_E_CERTIFICATE_KEY_MISMATCH
102 * is returned. On success, %GNUTLS_E_SUCCESS (0) is returned,
103 * or a negative error value on other errors.
105 * Since: 3.0
108 gnutls_verify_stored_pubkey(const char* db_name,
109 gnutls_tdb_t tdb,
110 const char* host,
111 const char* service,
112 gnutls_certificate_type_t cert_type,
113 const gnutls_datum_t * cert, unsigned int flags)
115 gnutls_datum_t pubkey = { NULL, 0 };
116 int ret;
117 char local_file[MAX_FILENAME];
119 if (cert_type != GNUTLS_CRT_X509 && cert_type != GNUTLS_CRT_OPENPGP)
120 return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE);
122 if (db_name == NULL && tdb == NULL)
124 ret = find_config_file(local_file, sizeof(local_file));
125 if (ret < 0)
126 return gnutls_assert_val(ret);
127 db_name = local_file;
130 if (tdb == NULL)
131 tdb = &default_tdb;
133 if (cert_type == GNUTLS_CRT_X509)
134 ret = x509_crt_to_raw_pubkey(cert, &pubkey);
135 else
136 ret = pgp_crt_to_raw_pubkey(cert, &pubkey);
138 if (ret < 0)
140 gnutls_assert();
141 goto cleanup;
144 ret = tdb->verify(db_name, host, service, &pubkey);
145 if (ret < 0 && ret != GNUTLS_E_CERTIFICATE_KEY_MISMATCH)
146 ret = gnutls_assert_val(GNUTLS_E_NO_CERTIFICATE_FOUND);
148 cleanup:
149 gnutls_free(pubkey.data);
150 return ret;
153 static int parse_commitment_line(char* line,
154 const char* host, size_t host_len,
155 const char* service, size_t service_len,
156 time_t now,
157 const gnutls_datum_t *skey)
159 char* p, *kp;
160 char* savep = NULL;
161 size_t kp_len, phash_size;
162 time_t expiration;
163 int ret;
164 gnutls_digest_algorithm_t hash_algo;
165 uint8_t phash[MAX_HASH_SIZE];
166 uint8_t hphash[MAX_HASH_SIZE*2+1];
168 /* read host */
169 p = strtok_r(line, "|", &savep);
170 if (p == NULL)
171 return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
173 if (p[0] != '*' && strcmp(p, host) != 0)
174 return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
176 /* read service */
177 p = strtok_r(NULL, "|", &savep);
178 if (p == NULL)
179 return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
181 if (p[0] != '*' && strcmp(p, service) != 0)
182 return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
184 /* read expiration */
185 p = strtok_r(NULL, "|", &savep);
186 if (p == NULL)
187 return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
189 expiration = (time_t)atol(p);
190 if (expiration > 0 && now > expiration)
191 return gnutls_assert_val(GNUTLS_E_EXPIRED);
193 /* read hash algorithm */
194 p = strtok_r(NULL, "|", &savep);
195 if (p == NULL)
196 return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
198 hash_algo = (time_t)atol(p);
199 if (_gnutls_digest_get_name(hash_algo) == NULL)
200 return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
202 /* read hash */
203 kp = strtok_r(NULL, "|", &savep);
204 if (kp == NULL)
205 return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
207 p = strpbrk(kp, "\n \r\t|");
208 if (p != NULL) *p = 0;
210 /* hash and hex encode */
211 ret = _gnutls_hash_fast (hash_algo, skey->data, skey->size, phash);
212 if (ret < 0)
213 return gnutls_assert_val(ret);
215 phash_size = _gnutls_hash_get_algo_len(hash_algo);
217 p = _gnutls_bin2hex (phash, phash_size,(void*) hphash,
218 sizeof(hphash), NULL);
219 if (p == NULL)
220 return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
222 kp_len = strlen(kp);
223 if (kp_len != phash_size*2)
224 return gnutls_assert_val(GNUTLS_E_CERTIFICATE_KEY_MISMATCH);
226 if (memcmp(kp, hphash, kp_len) != 0)
227 return gnutls_assert_val(GNUTLS_E_CERTIFICATE_KEY_MISMATCH);
229 /* key found and matches */
230 return 0;
234 static int parse_line(char* line,
235 const char* host, size_t host_len,
236 const char* service, size_t service_len,
237 time_t now,
238 const gnutls_datum_t *rawkey,
239 const gnutls_datum_t *b64key)
241 char* p, *kp;
242 char* savep = NULL;
243 size_t kp_len;
244 time_t expiration;
246 /* read version */
247 p = strtok_r(line, "|", &savep);
248 if (p == NULL)
249 return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
251 if (strncmp(p, "c0", 2) == 0)
252 return parse_commitment_line(p+3, host, host_len, service, service_len, now, rawkey);
254 if (strncmp(p, "g0", 2) != 0)
255 return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
257 /* read host */
258 p = strtok_r(NULL, "|", &savep);
259 if (p == NULL)
260 return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
262 if (p[0] != '*' && strcmp(p, host) != 0)
263 return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
265 /* read service */
266 p = strtok_r(NULL, "|", &savep);
267 if (p == NULL)
268 return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
270 if (p[0] != '*' && strcmp(p, service) != 0)
271 return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
273 /* read expiration */
274 p = strtok_r(NULL, "|", &savep);
275 if (p == NULL)
276 return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
278 expiration = (time_t)atol(p);
279 if (expiration > 0 && now > expiration)
280 return gnutls_assert_val(GNUTLS_E_EXPIRED);
282 /* read key */
283 kp = strtok_r(NULL, "|", &savep);
284 if (kp == NULL)
285 return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
287 p = strpbrk(kp, "\n \r\t|");
288 if (p != NULL) *p = 0;
290 kp_len = strlen(kp);
291 if (kp_len != b64key->size)
292 return gnutls_assert_val(GNUTLS_E_CERTIFICATE_KEY_MISMATCH);
294 if (memcmp(kp, b64key->data, b64key->size) != 0)
295 return gnutls_assert_val(GNUTLS_E_CERTIFICATE_KEY_MISMATCH);
297 /* key found and matches */
298 return 0;
301 /* Returns the base64 key if found
303 static int verify_pubkey(const char* file,
304 const char* host, const char* service,
305 const gnutls_datum_t* pubkey)
307 FILE* fd;
308 char* line = NULL;
309 size_t line_size = 0;
310 int ret, l2, mismatch = 0;
311 size_t host_len = 0, service_len = 0;
312 time_t now = gnutls_time(0);
313 gnutls_datum_t b64key = { NULL, 0 };
315 ret = raw_pubkey_to_base64(pubkey, &b64key);
316 if (ret < 0)
317 return gnutls_assert_val(ret);
319 if (host != NULL) host_len = strlen(host);
320 if (service != NULL) service_len = strlen(service);
322 fd = fopen(file, "rb");
323 if (fd == NULL)
325 ret = gnutls_assert_val(GNUTLS_E_FILE_ERROR);
326 goto cleanup;
331 l2 = getline(&line, &line_size, fd);
332 if (l2 > 0)
334 ret = parse_line(line, host, host_len, service, service_len, now, pubkey, &b64key);
335 if (ret == 0) /* found */
337 goto cleanup;
339 else if (ret == GNUTLS_E_CERTIFICATE_KEY_MISMATCH)
340 mismatch = 1;
343 while(l2 >= 0);
345 if (mismatch)
346 ret = GNUTLS_E_CERTIFICATE_KEY_MISMATCH;
347 else
348 ret = GNUTLS_E_NO_CERTIFICATE_FOUND;
350 cleanup:
351 free(line);
352 if (fd != NULL)
353 fclose(fd);
354 gnutls_free(b64key.data);
356 return ret;
359 static int raw_pubkey_to_base64(const gnutls_datum_t* raw, gnutls_datum_t * b64)
361 int ret;
362 char* out;
364 ret = base64_encode_alloc((void*)raw->data, raw->size, &out);
365 if (ret == 0)
366 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
368 b64->data = (void*)out;
369 b64->size = ret;
371 return 0;
374 static int x509_crt_to_raw_pubkey(const gnutls_datum_t * cert, gnutls_datum_t *rpubkey)
376 gnutls_x509_crt_t crt = NULL;
377 gnutls_pubkey_t pubkey = NULL;
378 size_t size;
379 int ret;
381 ret = gnutls_x509_crt_init(&crt);
382 if (ret < 0)
383 return gnutls_assert_val(ret);
385 ret = gnutls_pubkey_init(&pubkey);
386 if (ret < 0)
388 gnutls_assert();
389 goto cleanup;
392 ret = gnutls_x509_crt_import(crt, cert, GNUTLS_X509_FMT_DER);
393 if (ret < 0)
395 gnutls_assert();
396 goto cleanup;
399 ret = gnutls_pubkey_import_x509 (pubkey, crt, 0);
400 if (ret < 0)
402 gnutls_assert();
403 goto cleanup;
406 size = 0;
407 ret = gnutls_pubkey_export(pubkey, GNUTLS_X509_FMT_DER, NULL, &size);
408 if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
410 gnutls_assert();
411 goto cleanup;
414 rpubkey->data = gnutls_malloc(size);
415 if (rpubkey->data == NULL)
416 if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
418 ret = GNUTLS_E_MEMORY_ERROR;
419 gnutls_assert();
420 goto cleanup;
423 ret = gnutls_pubkey_export(pubkey, GNUTLS_X509_FMT_DER, rpubkey->data, &size);
424 if (ret < 0)
426 gnutls_free(rpubkey->data);
427 gnutls_assert();
428 goto cleanup;
431 rpubkey->size = size;
432 ret = 0;
434 cleanup:
435 gnutls_x509_crt_deinit(crt);
436 gnutls_pubkey_deinit(pubkey);
438 return ret;
441 static int pgp_crt_to_raw_pubkey(const gnutls_datum_t * cert, gnutls_datum_t *rpubkey)
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;
508 static
509 int store_pubkey(const char* db_name, const char* host,
510 const char* service, time_t expiration,
511 const gnutls_datum_t* pubkey)
513 FILE* fd = NULL;
514 gnutls_datum_t b64key = { NULL, 0 };
515 int ret;
517 ret = gnutls_mutex_lock(&_gnutls_file_mutex);
518 if (ret != 0)
519 return gnutls_assert_val(GNUTLS_E_LOCKING_ERROR);
521 ret = raw_pubkey_to_base64(pubkey, &b64key);
522 if (ret < 0)
524 gnutls_assert();
525 goto cleanup;
528 fd = fopen(db_name, "ab+");
529 if (fd == NULL)
531 ret = gnutls_assert_val(GNUTLS_E_FILE_ERROR);
532 goto cleanup;
535 if (service == NULL) service = "*";
536 if (host == NULL) host = "*";
538 fprintf(fd, "|g0|%s|%s|%lu|%.*s\n", host, service, (unsigned long)expiration,
539 b64key.size, b64key.data);
541 ret = 0;
543 cleanup:
544 if (fd != NULL)
545 fclose(fd);
547 gnutls_mutex_unlock(&_gnutls_file_mutex);
548 gnutls_free(b64key.data);
550 return ret;
553 static
554 int store_commitment(const char* db_name, const char* host,
555 const char* service, time_t expiration,
556 gnutls_digest_algorithm_t hash_algo,
557 const gnutls_datum_t* hash)
559 FILE* fd;
560 char buffer[MAX_HASH_SIZE*2+1];
562 fd = fopen(db_name, "ab+");
563 if (fd == NULL)
564 return gnutls_assert_val(GNUTLS_E_FILE_ERROR);
566 if (service == NULL) service = "*";
567 if (host == NULL) host = "*";
569 fprintf(fd, "|c0|%s|%s|%lu|%u|%s\n", host, service, (unsigned long)expiration,
570 (unsigned)hash_algo, _gnutls_bin2hex(hash->data, hash->size, buffer, sizeof(buffer), NULL));
572 fclose(fd);
574 return 0;
578 * gnutls_store_pubkey:
579 * @db_name: A file specifying the stored keys (use NULL for the default)
580 * @tdb: A storage structure or NULL to use the default
581 * @host: The peer's name
582 * @service: non-NULL if this key is specific to a service (e.g. http)
583 * @cert_type: The type of the certificate
584 * @cert: The data of the certificate
585 * @expiration: The expiration time (use 0 to disable expiration)
586 * @flags: should be 0.
588 * This function will store the provided certificate to
589 * the list of stored public keys. The key will be considered valid until
590 * the provided expiration time.
592 * The @store variable if non-null specifies a custom backend for
593 * the storage of entries. If it is NULL then the
594 * default file backend will be used.
596 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
597 * negative error value.
599 * Since: 3.0
602 gnutls_store_pubkey(const char* db_name,
603 gnutls_tdb_t tdb,
604 const char* host,
605 const char* service,
606 gnutls_certificate_type_t cert_type,
607 const gnutls_datum_t * cert,
608 time_t expiration,
609 unsigned int flags)
611 FILE* fd = NULL;
612 gnutls_datum_t pubkey = { NULL, 0 };
613 int ret;
614 char local_file[MAX_FILENAME];
616 if (cert_type != GNUTLS_CRT_X509 && cert_type != GNUTLS_CRT_OPENPGP)
617 return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE);
619 if (db_name == NULL && tdb == NULL)
621 ret = _gnutls_find_config_path(local_file, sizeof(local_file));
622 if (ret < 0)
623 return gnutls_assert_val(ret);
625 _gnutls_debug_log("Configuration path: %s\n", local_file);
626 mkdir(local_file, 0700);
628 ret = find_config_file(local_file, sizeof(local_file));
629 if (ret < 0)
630 return gnutls_assert_val(ret);
631 db_name = local_file;
634 if (tdb == NULL)
635 tdb = &default_tdb;
637 if (cert_type == GNUTLS_CRT_X509)
638 ret = x509_crt_to_raw_pubkey(cert, &pubkey);
639 else
640 ret = pgp_crt_to_raw_pubkey(cert, &pubkey);
641 if (ret < 0)
643 gnutls_assert();
644 goto cleanup;
647 _gnutls_debug_log("Configuration file: %s\n", db_name);
649 tdb->store(db_name, host, service, expiration, &pubkey);
651 ret = 0;
653 cleanup:
654 gnutls_free(pubkey.data);
655 if (fd != NULL) fclose(fd);
657 return ret;
661 * gnutls_store_commitment:
662 * @db_name: A file specifying the stored keys (use NULL for the default)
663 * @tdb: A storage structure or NULL to use the default
664 * @host: The peer's name
665 * @service: non-NULL if this key is specific to a service (e.g. http)
666 * @hash_algo: The hash algorithm type
667 * @hash: The raw hash
668 * @expiration: The expiration time (use 0 to disable expiration)
669 * @flags: should be 0.
671 * This function will store the provided hash commitment to
672 * the list of stored public keys. The key with the given
673 * hash will be considered valid until the provided expiration time.
675 * The @store variable if non-null specifies a custom backend for
676 * the storage of entries. If it is NULL then the
677 * default file backend will be used.
679 * Note that this function is not thread safe with the default backend.
681 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
682 * negative error value.
684 * Since: 3.0
687 gnutls_store_commitment(const char* db_name,
688 gnutls_tdb_t tdb,
689 const char* host,
690 const char* service,
691 gnutls_digest_algorithm_t hash_algo,
692 const gnutls_datum_t* hash,
693 time_t expiration,
694 unsigned int flags)
696 FILE* fd = NULL;
697 int ret;
698 char local_file[MAX_FILENAME];
700 if (hash_algo == GNUTLS_DIG_MD5 || hash_algo == GNUTLS_DIG_MD2)
701 return gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
703 if (_gnutls_hash_get_algo_len(hash_algo) != hash->size)
704 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
706 if (db_name == NULL && tdb == NULL)
708 ret = _gnutls_find_config_path(local_file, sizeof(local_file));
709 if (ret < 0)
710 return gnutls_assert_val(ret);
712 _gnutls_debug_log("Configuration path: %s\n", local_file);
713 mkdir(local_file, 0700);
715 ret = find_config_file(local_file, sizeof(local_file));
716 if (ret < 0)
717 return gnutls_assert_val(ret);
718 db_name = local_file;
721 if (tdb == NULL)
722 tdb = &default_tdb;
724 _gnutls_debug_log("Configuration file: %s\n", db_name);
726 tdb->cstore(db_name, host, service, expiration, hash_algo, hash);
728 ret = 0;
730 if (fd != NULL) fclose(fd);
732 return ret;
735 #define CONFIG_FILE "known_hosts"
737 static int find_config_file(char* file, size_t max_size)
739 char path[MAX_FILENAME];
740 int ret;
742 ret = _gnutls_find_config_path(path, sizeof(path));
743 if (ret < 0)
744 return gnutls_assert_val(ret);
746 if (path[0] == 0)
747 snprintf(file, max_size, "%s", CONFIG_FILE);
748 else
749 snprintf(file, max_size, "%s/%s", path, CONFIG_FILE);
751 return 0;
755 * gnutls_tdb_init:
756 * @tdb: The structure to be initialized
758 * This function will initialize a public key trust storage structure.
760 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
761 * negative error value.
763 int gnutls_tdb_init(gnutls_tdb_t* tdb)
765 *tdb = gnutls_calloc (1, sizeof (struct gnutls_tdb_int));
767 if (!*tdb)
768 return GNUTLS_E_MEMORY_ERROR;
770 return 0;
774 * gnutls_set_store_func:
775 * @tdb: The trust storage
776 * @store: The storage function
778 * This function will associate a storage function with the
779 * trust storage structure. The function is of the following form.
781 * gnutls_tdb_store_func(const char* db_name, const char* host,
782 * const char* service, time_t expiration,
783 * const gnutls_datum_t* pubkey);
786 void gnutls_tdb_set_store_func(gnutls_tdb_t tdb, gnutls_tdb_store_func store)
788 tdb->store = store;
792 * gnutls_set_store_commitment_func:
793 * @tdb: The trust storage
794 * @cstore: The commitment storage function
796 * This function will associate a commitment (hash) storage function with the
797 * trust storage structure. The function is of the following form.
799 * gnutls_tdb_store_commitment_func(const char* db_name, const char* host,
800 * const char* service, time_t expiration,
801 * gnutls_digest_algorithm_t, const gnutls_datum_t* hash);
804 void gnutls_tdb_set_store_commitment_func(gnutls_tdb_t tdb,
805 gnutls_tdb_store_commitment_func cstore)
807 tdb->cstore = cstore;
811 * gnutls_set_verify_func:
812 * @tdb: The trust storage
813 * @verify: The verification function
815 * This function will associate a retrieval function with the
816 * trust storage structure. The function is of the following form.
818 * gnutls_tdb_verify_func(const char* db_name, const char* host,
819 * const char* service, const gnutls_datum_t* pubkey);
822 void gnutls_tdb_set_verify_func(gnutls_tdb_t tdb, gnutls_tdb_verify_func verify)
824 tdb->verify = verify;
828 * gnutls_tdb_deinit:
829 * @tdb: The structure to be deinitialized
831 * This function will deinitialize a public key trust storage structure.
833 void gnutls_tdb_deinit(gnutls_tdb_t tdb)
835 gnutls_free(tdb);