Correctly restore gnutls_record_recv() in DTLS mode if interrupted during the retrasm...
[gnutls.git] / lib / verify-tofu.c
blob5b2ce172059882dde69958de00f65dd579e70430
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 #ifdef ENABLE_OPENPGP
444 gnutls_openpgp_crt_t crt = NULL;
445 gnutls_pubkey_t pubkey = NULL;
446 size_t size;
447 int ret;
449 ret = gnutls_openpgp_crt_init(&crt);
450 if (ret < 0)
451 return gnutls_assert_val(ret);
453 ret = gnutls_pubkey_init(&pubkey);
454 if (ret < 0)
456 gnutls_assert();
457 goto cleanup;
460 ret = gnutls_openpgp_crt_import(crt, cert, GNUTLS_OPENPGP_FMT_RAW);
461 if (ret < 0)
463 gnutls_assert();
464 goto cleanup;
467 ret = gnutls_pubkey_import_openpgp (pubkey, crt, 0);
468 if (ret < 0)
470 gnutls_assert();
471 goto cleanup;
474 size = 0;
475 ret = gnutls_pubkey_export(pubkey, GNUTLS_X509_FMT_DER, NULL, &size);
476 if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
478 gnutls_assert();
479 goto cleanup;
482 rpubkey->data = gnutls_malloc(size);
483 if (rpubkey->data == NULL)
484 if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
486 ret = GNUTLS_E_MEMORY_ERROR;
487 gnutls_assert();
488 goto cleanup;
491 ret = gnutls_pubkey_export(pubkey, GNUTLS_X509_FMT_DER, rpubkey->data, &size);
492 if (ret < 0)
494 gnutls_free(rpubkey->data);
495 gnutls_assert();
496 goto cleanup;
499 rpubkey->size = size;
500 ret = 0;
502 cleanup:
503 gnutls_openpgp_crt_deinit(crt);
504 gnutls_pubkey_deinit(pubkey);
506 return ret;
507 #else
508 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
509 #endif
512 static
513 int store_pubkey(const char* db_name, const char* host,
514 const char* service, time_t expiration,
515 const gnutls_datum_t* pubkey)
517 FILE* fd = NULL;
518 gnutls_datum_t b64key = { NULL, 0 };
519 int ret;
521 ret = gnutls_mutex_lock(&_gnutls_file_mutex);
522 if (ret != 0)
523 return gnutls_assert_val(GNUTLS_E_LOCKING_ERROR);
525 ret = raw_pubkey_to_base64(pubkey, &b64key);
526 if (ret < 0)
528 gnutls_assert();
529 goto cleanup;
532 fd = fopen(db_name, "ab+");
533 if (fd == NULL)
535 ret = gnutls_assert_val(GNUTLS_E_FILE_ERROR);
536 goto cleanup;
539 if (service == NULL) service = "*";
540 if (host == NULL) host = "*";
542 fprintf(fd, "|g0|%s|%s|%lu|%.*s\n", host, service, (unsigned long)expiration,
543 b64key.size, b64key.data);
545 ret = 0;
547 cleanup:
548 if (fd != NULL)
549 fclose(fd);
551 gnutls_mutex_unlock(&_gnutls_file_mutex);
552 gnutls_free(b64key.data);
554 return ret;
557 static
558 int store_commitment(const char* db_name, const char* host,
559 const char* service, time_t expiration,
560 gnutls_digest_algorithm_t hash_algo,
561 const gnutls_datum_t* hash)
563 FILE* fd;
564 char buffer[MAX_HASH_SIZE*2+1];
566 fd = fopen(db_name, "ab+");
567 if (fd == NULL)
568 return gnutls_assert_val(GNUTLS_E_FILE_ERROR);
570 if (service == NULL) service = "*";
571 if (host == NULL) host = "*";
573 fprintf(fd, "|c0|%s|%s|%lu|%u|%s\n", host, service, (unsigned long)expiration,
574 (unsigned)hash_algo, _gnutls_bin2hex(hash->data, hash->size, buffer, sizeof(buffer), NULL));
576 fclose(fd);
578 return 0;
582 * gnutls_store_pubkey:
583 * @db_name: A file specifying the stored keys (use NULL for the default)
584 * @tdb: A storage structure or NULL to use the default
585 * @host: The peer's name
586 * @service: non-NULL if this key is specific to a service (e.g. http)
587 * @cert_type: The type of the certificate
588 * @cert: The data of the certificate
589 * @expiration: The expiration time (use 0 to disable expiration)
590 * @flags: should be 0.
592 * This function will store the provided certificate to
593 * the list of stored public keys. The key will be considered valid until
594 * the provided expiration time.
596 * The @store variable if non-null specifies a custom backend for
597 * the storage of entries. If it is NULL then the
598 * default file backend will be used.
600 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
601 * negative error value.
603 * Since: 3.0
606 gnutls_store_pubkey(const char* db_name,
607 gnutls_tdb_t tdb,
608 const char* host,
609 const char* service,
610 gnutls_certificate_type_t cert_type,
611 const gnutls_datum_t * cert,
612 time_t expiration,
613 unsigned int flags)
615 FILE* fd = NULL;
616 gnutls_datum_t pubkey = { NULL, 0 };
617 int ret;
618 char local_file[MAX_FILENAME];
620 if (cert_type != GNUTLS_CRT_X509 && cert_type != GNUTLS_CRT_OPENPGP)
621 return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE);
623 if (db_name == NULL && tdb == NULL)
625 ret = _gnutls_find_config_path(local_file, sizeof(local_file));
626 if (ret < 0)
627 return gnutls_assert_val(ret);
629 _gnutls_debug_log("Configuration path: %s\n", local_file);
630 mkdir(local_file, 0700);
632 ret = find_config_file(local_file, sizeof(local_file));
633 if (ret < 0)
634 return gnutls_assert_val(ret);
635 db_name = local_file;
638 if (tdb == NULL)
639 tdb = &default_tdb;
641 if (cert_type == GNUTLS_CRT_X509)
642 ret = x509_crt_to_raw_pubkey(cert, &pubkey);
643 else
644 ret = pgp_crt_to_raw_pubkey(cert, &pubkey);
645 if (ret < 0)
647 gnutls_assert();
648 goto cleanup;
651 _gnutls_debug_log("Configuration file: %s\n", db_name);
653 tdb->store(db_name, host, service, expiration, &pubkey);
655 ret = 0;
657 cleanup:
658 gnutls_free(pubkey.data);
659 if (fd != NULL) fclose(fd);
661 return ret;
665 * gnutls_store_commitment:
666 * @db_name: A file specifying the stored keys (use NULL for the default)
667 * @tdb: A storage structure or NULL to use the default
668 * @host: The peer's name
669 * @service: non-NULL if this key is specific to a service (e.g. http)
670 * @hash_algo: The hash algorithm type
671 * @hash: The raw hash
672 * @expiration: The expiration time (use 0 to disable expiration)
673 * @flags: should be 0.
675 * This function will store the provided hash commitment to
676 * the list of stored public keys. The key with the given
677 * hash will be considered valid until the provided expiration time.
679 * The @store variable if non-null specifies a custom backend for
680 * the storage of entries. If it is NULL then the
681 * default file backend will be used.
683 * Note that this function is not thread safe with the default backend.
685 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
686 * negative error value.
688 * Since: 3.0
691 gnutls_store_commitment(const char* db_name,
692 gnutls_tdb_t tdb,
693 const char* host,
694 const char* service,
695 gnutls_digest_algorithm_t hash_algo,
696 const gnutls_datum_t* hash,
697 time_t expiration,
698 unsigned int flags)
700 FILE* fd = NULL;
701 int ret;
702 char local_file[MAX_FILENAME];
704 if (hash_algo == GNUTLS_DIG_MD5 || hash_algo == GNUTLS_DIG_MD2)
705 return gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
707 if (_gnutls_hash_get_algo_len(hash_algo) != hash->size)
708 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
710 if (db_name == NULL && tdb == NULL)
712 ret = _gnutls_find_config_path(local_file, sizeof(local_file));
713 if (ret < 0)
714 return gnutls_assert_val(ret);
716 _gnutls_debug_log("Configuration path: %s\n", local_file);
717 mkdir(local_file, 0700);
719 ret = find_config_file(local_file, sizeof(local_file));
720 if (ret < 0)
721 return gnutls_assert_val(ret);
722 db_name = local_file;
725 if (tdb == NULL)
726 tdb = &default_tdb;
728 _gnutls_debug_log("Configuration file: %s\n", db_name);
730 tdb->cstore(db_name, host, service, expiration, hash_algo, hash);
732 ret = 0;
734 if (fd != NULL) fclose(fd);
736 return ret;
739 #define CONFIG_FILE "known_hosts"
741 static int find_config_file(char* file, size_t max_size)
743 char path[MAX_FILENAME];
744 int ret;
746 ret = _gnutls_find_config_path(path, sizeof(path));
747 if (ret < 0)
748 return gnutls_assert_val(ret);
750 if (path[0] == 0)
751 snprintf(file, max_size, "%s", CONFIG_FILE);
752 else
753 snprintf(file, max_size, "%s/%s", path, CONFIG_FILE);
755 return 0;
759 * gnutls_tdb_init:
760 * @tdb: The structure to be initialized
762 * This function will initialize a public key trust storage structure.
764 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
765 * negative error value.
767 int gnutls_tdb_init(gnutls_tdb_t* tdb)
769 *tdb = gnutls_calloc (1, sizeof (struct gnutls_tdb_int));
771 if (!*tdb)
772 return GNUTLS_E_MEMORY_ERROR;
774 return 0;
778 * gnutls_set_store_func:
779 * @tdb: The trust storage
780 * @store: The storage function
782 * This function will associate a storage function with the
783 * trust storage structure. The function is of the following form.
785 * gnutls_tdb_store_func(const char* db_name, const char* host,
786 * const char* service, time_t expiration,
787 * const gnutls_datum_t* pubkey);
790 void gnutls_tdb_set_store_func(gnutls_tdb_t tdb, gnutls_tdb_store_func store)
792 tdb->store = store;
796 * gnutls_set_store_commitment_func:
797 * @tdb: The trust storage
798 * @cstore: The commitment storage function
800 * This function will associate a commitment (hash) storage function with the
801 * trust storage structure. The function is of the following form.
803 * gnutls_tdb_store_commitment_func(const char* db_name, const char* host,
804 * const char* service, time_t expiration,
805 * gnutls_digest_algorithm_t, const gnutls_datum_t* hash);
808 void gnutls_tdb_set_store_commitment_func(gnutls_tdb_t tdb,
809 gnutls_tdb_store_commitment_func cstore)
811 tdb->cstore = cstore;
815 * gnutls_set_verify_func:
816 * @tdb: The trust storage
817 * @verify: The verification function
819 * This function will associate a retrieval function with the
820 * trust storage structure. The function is of the following form.
822 * gnutls_tdb_verify_func(const char* db_name, const char* host,
823 * const char* service, const gnutls_datum_t* pubkey);
826 void gnutls_tdb_set_verify_func(gnutls_tdb_t tdb, gnutls_tdb_verify_func verify)
828 tdb->verify = verify;
832 * gnutls_tdb_deinit:
833 * @tdb: The structure to be deinitialized
835 * This function will deinitialize a public key trust storage structure.
837 void gnutls_tdb_deinit(gnutls_tdb_t tdb)
839 gnutls_free(tdb);