Removed unused parameter.
[gnutls:gnutls.git] / libdane / dane.c
1 /*
2  * Copyright (C) 2012 KU Leuven
3  * Copyright (C) 2013 Christian Grothoff
4  * Copyright (C) 2013 Nikos Mavrogiannopoulos
5  *
6  * Author: Nikos Mavrogiannopoulos
7  *
8  * This file is part of libdane.
9  *
10  * The libdane library is free software; you can redistribute it
11  * and/or modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful, but
16  * WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with this program.  If not, see <http://www.gnu.org/licenses/>
22  *
23  */
24
25 #include <config.h>
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <errno.h>
31 #include <arpa/inet.h>
32 #include <unbound.h>
33 #include <gnutls/dane.h>
34 #include <gnutls/x509.h>
35 #include <gnutls/abstract.h>
36 #include <gnutls/crypto.h>
37 #include "../lib/gnutls_int.h"
38
39 #define MAX_DATA_ENTRIES 4
40
41 #ifdef DEBUG
42 #define gnutls_assert() fprintf(stderr, "ASSERT: %s: %d\n", __FILE__, __LINE__);
43 #define gnutls_assert_val(x) gnutls_assert_val_int(x, __FILE__, __LINE__)
44 static int
45 gnutls_assert_val_int (int val, const char *file, int line)
46 {
47   fprintf (stderr, "ASSERT: %s: %d\n", file, line);
48   return val;
49 }
50 #else
51 #define gnutls_assert()
52 #define gnutls_assert_val(x) (x)
53 #endif
54
55 struct dane_state_st
56 {
57   struct ub_ctx *ctx;
58   unsigned int flags;
59 };
60
61 struct dane_query_st
62 {
63   struct ub_result *result;
64   unsigned int data_entries;
65   dane_cert_usage_t usage[MAX_DATA_ENTRIES];
66   dane_cert_type_t type[MAX_DATA_ENTRIES];
67   dane_match_type_t match[MAX_DATA_ENTRIES];
68   gnutls_datum_t data[MAX_DATA_ENTRIES];
69   unsigned int flags;
70   dane_query_status_t status;
71 };
72
73 /**
74  * dane_query_status:
75  * @q: The query result structure
76  *
77  * This function will return the status of the query response.
78  * See %dane_query_status_t for the possible types.
79  *
80  * Returns: The status type.
81  **/
82 dane_query_status_t
83 dane_query_status (dane_query_t q)
84 {
85   return q->status;
86 }
87
88 /**
89  * dane_query_entries:
90  * @q: The query result structure
91  *
92  * This function will return the number of entries in a query.
93  *
94  * Returns: The number of entries.
95  **/
96 unsigned int
97 dane_query_entries (dane_query_t q)
98 {
99   return q->data_entries;
100 }
101
102 /**
103  * dane_query_data:
104  * @q: The query result structure
105  * @idx: The index of the query response.
106  * @usage: The certificate usage (see %dane_cert_usage_t)
107  * @type: The certificate type (see %dane_cert_type_t)
108  * @match: The DANE matching type (see %dane_match_type_t)
109  * @data: The DANE data.
110  *
111  * This function will provide the DANE data from the query
112  * response.
113  *
114  * Returns: On success, %DANE_E_SUCCESS (0) is returned, otherwise a
115  *   negative error value.
116  **/
117 int
118 dane_query_data (dane_query_t q, unsigned int idx,
119                  unsigned int *usage, unsigned int *type,
120                  unsigned int *match, gnutls_datum_t * data)
121 {
122   if (idx >= q->data_entries)
123     return gnutls_assert_val (DANE_E_REQUESTED_DATA_NOT_AVAILABLE);
124
125   if (usage)
126     *usage = q->usage[idx];
127   if (type)
128     *type = q->type[idx];
129   if (match)
130     *match = q->match[idx];
131   if (data)
132     {
133       data->data = q->data[idx].data;
134       data->size = q->data[idx].size;
135     }
136
137   return DANE_E_SUCCESS;
138 }
139
140 /**
141  * dane_state_init:
142  * @s: The structure to be initialized
143  * @flags: flags from the %dane_state_flags enumeration
144  *
145  * This function will initialize a DANE query structure.
146  *
147  * Returns: On success, %DANE_E_SUCCESS (0) is returned, otherwise a
148  *   negative error value.
149  **/
150 int
151 dane_state_init (dane_state_t * s, unsigned int flags)
152 {
153   struct ub_ctx *ctx;
154   int ret;
155
156   *s = calloc (1, sizeof (struct dane_state_st));
157   if (*s == NULL)
158     return gnutls_assert_val (DANE_E_MEMORY_ERROR);
159
160   ctx = ub_ctx_create ();
161   if (!ctx)
162     {
163       gnutls_assert ();
164       ret = DANE_E_INITIALIZATION_ERROR;
165       goto cleanup;
166     }
167   ub_ctx_debugout (ctx, stderr);
168
169   if (!(flags & DANE_F_IGNORE_LOCAL_RESOLVER))
170     {
171       if ((ret = ub_ctx_resolvconf (ctx, NULL)) != 0)
172         {
173           gnutls_assert ();
174           ret = DANE_E_INITIALIZATION_ERROR;
175           goto cleanup;
176         }
177
178       if ((ret = ub_ctx_hosts (ctx, NULL)) != 0)
179         {
180           gnutls_assert ();
181           ret = DANE_E_INITIALIZATION_ERROR;
182           goto cleanup;
183         }
184     }
185
186   /* read public keys for DNSSEC verification */
187   if (!(flags & DANE_F_IGNORE_DNSSEC))
188     {
189       if ((ret =
190            ub_ctx_add_ta_file (ctx, (char *) UNBOUND_ROOT_KEY_FILE)) != 0)
191         {
192           gnutls_assert ();
193           ret = DANE_E_INITIALIZATION_ERROR;
194           goto cleanup;
195         }
196     }
197
198   (*s)->ctx = ctx;
199   (*s)->flags = flags;
200
201   return DANE_E_SUCCESS;
202 cleanup:
203
204   if (ctx)
205     ub_ctx_delete (ctx);
206   free (*s);
207
208   return ret;
209 }
210
211 /**
212  * dane_state_deinit:
213  * @s: The structure to be deinitialized
214  *
215  * This function will deinitialize a DANE query structure.
216  *
217  **/
218 void
219 dane_state_deinit (dane_state_t s)
220 {
221   ub_ctx_delete (s->ctx);
222   free (s);
223 }
224
225 /**
226  * dane_state_set_dlv_file:
227  * @s: The structure to be deinitialized
228  * @file: The file holding the DLV keys.
229  *
230  * This function will set a file with trusted keys
231  * for DLV  (DNSSEC  Lookaside  Validation).
232  *
233  **/
234 int
235 dane_state_set_dlv_file (dane_state_t s, const char *file)
236 {
237   int ret;
238
239   ret =
240     ub_ctx_set_option (s->ctx, (char *) "dlv-anchor-file:", (void *) file);
241   if (ret != 0)
242     return gnutls_assert_val (DANE_E_FILE_ERROR);
243
244   return 0;
245 }
246
247 /**
248  * dane_query_deinit:
249  * @q: The structure to be deinitialized
250  *
251  * This function will deinitialize a DANE query result structure.
252  *
253  **/
254 void
255 dane_query_deinit (dane_query_t q)
256 {
257   if (q->result)
258     ub_resolve_free (q->result);
259   free (q);
260 }
261
262
263 /**
264  * dane_raw_tlsa:
265  * @s: The DANE state structure
266  * @r: A structure to place the result
267  * @dane_data: array of DNS rdata items, terminated with a NULL pointer;
268  *             caller must guarantee that the referenced data remains
269  *             valid until dane_query_deinit() is called.
270  * @dane_data_len: the length n bytes of the dane_data items
271  * @secure: true if the result is validated securely, false if
272  *               validation failed or the domain queried has no security info
273  * @bogus: if the result was not secure (secure = 0) due to a security failure,
274  *              and the result is due to a security failure, bogus is true.
275  *
276  * This function will fill in the TLSA (DANE) structure from
277  * the given raw DNS record data.
278  *
279  * Returns: On success, %DANE_E_SUCCESS (0) is returned, otherwise a
280  *   negative error value.
281  **/
282 int
283 dane_raw_tlsa (dane_state_t s, dane_query_t * r, char *const *dane_data,
284                const int *dane_data_len, int secure, int bogus)
285 {
286   int ret = DANE_E_SUCCESS;
287   unsigned int i;
288
289   *r = calloc (1, sizeof (struct dane_query_st));
290   if (*r == NULL)
291     return gnutls_assert_val (DANE_E_MEMORY_ERROR);
292
293   (*r)->data_entries = 0;
294
295   for (i = 0; i < MAX_DATA_ENTRIES; i++)
296     {
297       if (dane_data[i] == NULL)
298         break;
299
300       if (dane_data_len[i] <= 3)
301         return gnutls_assert_val (DANE_E_RECEIVED_CORRUPT_DATA);
302
303       (*r)->usage[i] = dane_data[i][0];
304       (*r)->type[i] = dane_data[i][1];
305       (*r)->match[i] = dane_data[i][2];
306       (*r)->data[i].data = (void *) &dane_data[i][3];
307       (*r)->data[i].size = dane_data_len[i] - 3;
308       (*r)->data_entries++;
309     }
310
311   if (!(s->flags & DANE_F_INSECURE) && !secure)
312     {
313       if (bogus)
314         ret = gnutls_assert_val (DANE_E_INVALID_DNSSEC_SIG);
315       else
316         ret = gnutls_assert_val (DANE_E_NO_DNSSEC_SIG);
317     }
318
319   /* show security status */
320   if (secure)
321     {
322       (*r)->status = DANE_QUERY_DNSSEC_VERIFIED;
323     }
324   else if (bogus)
325     {
326       gnutls_assert ();
327       (*r)->status = DANE_QUERY_BOGUS;
328     }
329   else
330     {
331       gnutls_assert ();
332       (*r)->status = DANE_QUERY_NO_DNSSEC;
333     }
334
335   return ret;
336 }
337
338
339 /**
340  * dane_query_tlsa:
341  * @s: The DANE state structure
342  * @r: A structure to place the result
343  * @host: The host name to resolve.
344  * @proto: The protocol type (tcp, udp, etc.)
345  * @port: The service port number (eg. 443).
346  *
347  * This function will query the DNS server for the TLSA (DANE)
348  * data for the given host.
349  *
350  * Returns: On success, %DANE_E_SUCCESS (0) is returned, otherwise a
351  *   negative error value.
352  **/
353 int
354 dane_query_tlsa (dane_state_t s, dane_query_t * r, const char *host,
355                  const char *proto, unsigned int port)
356 {
357   char ns[1024];
358   int ret;
359   struct ub_result *result;
360
361   snprintf (ns, sizeof (ns), "_%u._%s.%s", port, proto, host);
362
363   /* query for webserver */
364   ret = ub_resolve (s->ctx, ns, 52, 1, &result);
365   if (ret != 0)
366     {
367       return gnutls_assert_val (DANE_E_RESOLVING_ERROR);
368     }
369
370 /* show first result */
371   if (!result->havedata)
372     {
373       ub_resolve_free (result);
374       return gnutls_assert_val (DANE_E_NO_DANE_DATA);
375     }
376
377   ret =
378     dane_raw_tlsa (s, r, result->data, result->len, result->secure,
379                    result->bogus);
380   if (*r == NULL)
381     {
382       ub_resolve_free (result);
383       return ret;
384     }
385   (*r)->result = result;
386   return ret;
387 }
388
389
390 static unsigned int
391 matches (const gnutls_datum_t * raw1, const gnutls_datum_t * raw2,
392          dane_match_type_t match)
393 {
394   uint8_t digest[64];
395   int ret;
396
397   if (match == DANE_MATCH_EXACT)
398     {
399       if (raw1->size != raw2->size)
400         return gnutls_assert_val (0);
401
402       if (memcmp (raw1->data, raw2->data, raw1->size) != 0)
403         return gnutls_assert_val (0);
404
405       return 1;
406     }
407   else if (match == DANE_MATCH_SHA2_256)
408     {
409
410       if (raw2->size != 32)
411         return gnutls_assert_val (0);
412
413       ret =
414         gnutls_hash_fast (GNUTLS_DIG_SHA256, raw1->data, raw1->size, digest);
415       if (ret < 0)
416         return gnutls_assert_val (0);
417
418       if (memcmp (digest, raw2->data, 32) != 0)
419         return gnutls_assert_val (0);
420
421       return 1;
422     }
423   else if (match == DANE_MATCH_SHA2_512)
424     {
425       if (raw2->size != 64)
426         return gnutls_assert_val (0);
427
428       ret =
429         gnutls_hash_fast (GNUTLS_DIG_SHA512, raw1->data, raw1->size, digest);
430       if (ret < 0)
431         return gnutls_assert_val (0);
432
433       if (memcmp (digest, raw2->data, 64) != 0)
434         return gnutls_assert_val (0);
435
436       return 1;
437     }
438
439   return gnutls_assert_val (0);
440 }
441
442 static int
443 crt_to_pubkey (const gnutls_datum_t * raw_crt, gnutls_datum_t * out)
444 {
445   gnutls_pubkey_t pub = NULL;
446   gnutls_x509_crt_t crt = NULL;
447   int ret;
448
449   out->data = NULL;
450
451   ret = gnutls_x509_crt_init (&crt);
452   if (ret < 0)
453     return gnutls_assert_val (DANE_E_PUBKEY_ERROR);
454
455   ret = gnutls_pubkey_init (&pub);
456   if (ret < 0)
457     {
458       gnutls_assert ();
459       ret = DANE_E_PUBKEY_ERROR;
460       goto cleanup;
461     }
462
463   ret = gnutls_x509_crt_import (crt, raw_crt, GNUTLS_X509_FMT_DER);
464   if (ret < 0)
465     {
466       gnutls_assert ();
467       ret = DANE_E_PUBKEY_ERROR;
468       goto cleanup;
469     }
470
471   ret = gnutls_pubkey_import_x509 (pub, crt, 0);
472   if (ret < 0)
473     {
474       gnutls_assert ();
475       ret = DANE_E_PUBKEY_ERROR;
476       goto cleanup;
477     }
478
479   ret = gnutls_pubkey_export2 (pub, GNUTLS_X509_FMT_DER, out);
480   if (ret < 0)
481     {
482       gnutls_assert ();
483       ret = DANE_E_PUBKEY_ERROR;
484       goto cleanup;
485     }
486
487   ret = 0;
488   goto clean_certs;
489
490 cleanup:
491   free (out->data);
492   out->data = NULL;
493 clean_certs:
494   if (pub)
495     gnutls_pubkey_deinit (pub);
496   if (crt)
497     gnutls_x509_crt_deinit (crt);
498
499   return ret;
500 }
501
502 static int
503 verify_ca (const gnutls_datum_t * raw_crt, unsigned raw_crt_size,
504            gnutls_certificate_type_t crt_type,
505            dane_cert_type_t ctype,
506            dane_match_type_t match, gnutls_datum_t * data,
507            unsigned int *verify)
508 {
509   gnutls_datum_t pubkey = { NULL, 0 };
510   int ret;
511   unsigned int vstatus;
512   gnutls_x509_crt_t crt = NULL, ca = NULL;
513
514   if (raw_crt_size < 2)
515     return gnutls_assert_val (DANE_E_INVALID_REQUEST);
516
517   if (ctype == DANE_CERT_X509 && crt_type == GNUTLS_CRT_X509)
518     {
519
520       if (!matches (&raw_crt[1], data, match))
521         {
522           gnutls_assert ();
523           *verify |= DANE_VERIFY_CA_CONSTRAINTS_VIOLATED;
524         }
525
526     }
527   else if (ctype == DANE_CERT_PK && crt_type == GNUTLS_CRT_X509)
528     {
529       ret = crt_to_pubkey (&raw_crt[1], &pubkey);
530       if (ret < 0)
531         {
532           gnutls_assert ();
533           goto cleanup;
534         }
535
536       if (!matches (&pubkey, data, match))
537         {
538           gnutls_assert ();
539           *verify |= DANE_VERIFY_CA_CONSTRAINTS_VIOLATED;
540         }
541     }
542   else
543     {
544       ret = gnutls_assert_val (DANE_E_UNKNOWN_DANE_DATA);
545       goto cleanup;
546     }
547
548   /* check if the certificate chain is actually a chain */
549   ret = gnutls_x509_crt_init (&crt);
550   if (ret < 0)
551     {
552       ret = gnutls_assert_val (DANE_E_CERT_ERROR);
553       goto cleanup;
554     }
555
556   ret = gnutls_x509_crt_init (&ca);
557   if (ret < 0)
558     {
559       ret = gnutls_assert_val (DANE_E_CERT_ERROR);
560       goto cleanup;
561     }
562
563   ret = gnutls_x509_crt_import (crt, &raw_crt[0], GNUTLS_X509_FMT_DER);
564   if (ret < 0)
565     {
566       ret = gnutls_assert_val (DANE_E_CERT_ERROR);
567       goto cleanup;
568     }
569
570   ret = gnutls_x509_crt_import (ca, &raw_crt[1], GNUTLS_X509_FMT_DER);
571   if (ret < 0)
572     {
573       ret = gnutls_assert_val (DANE_E_CERT_ERROR);
574       goto cleanup;
575     }
576
577   ret = gnutls_x509_crt_check_issuer (crt, ca);
578   if (ret == 0)
579     {
580       gnutls_assert ();
581       *verify |= DANE_VERIFY_CA_CONSTRAINTS_VIOLATED;
582     }
583
584   ret = gnutls_x509_crt_verify (crt, &ca, 1, 0, &vstatus);
585   if (ret < 0)
586     {
587       ret = gnutls_assert_val (DANE_E_CERT_ERROR);
588       goto cleanup;
589     }
590   if (vstatus != 0)
591     *verify |= DANE_VERIFY_CA_CONSTRAINTS_VIOLATED;
592
593   ret = 0;
594 cleanup:
595   free (pubkey.data);
596   if (crt != NULL)
597     gnutls_x509_crt_deinit (crt);
598   if (ca != NULL)
599     gnutls_x509_crt_deinit (ca);
600   return ret;
601 }
602
603 static int
604 verify_ee (const gnutls_datum_t * raw_crt, gnutls_certificate_type_t crt_type,
605            dane_cert_type_t ctype, dane_match_type_t match,
606            gnutls_datum_t * data, unsigned int *verify)
607 {
608   gnutls_datum_t pubkey = { NULL, 0 };
609   int ret;
610
611   if (ctype == DANE_CERT_X509 && crt_type == GNUTLS_CRT_X509)
612     {
613
614       if (!matches (raw_crt, data, match))
615         {
616           gnutls_assert ();
617           *verify |= DANE_VERIFY_CERT_DIFFERS;
618         }
619
620     }
621   else if (ctype == DANE_CERT_PK && crt_type == GNUTLS_CRT_X509)
622     {
623
624       ret = crt_to_pubkey (raw_crt, &pubkey);
625       if (ret < 0)
626         {
627           gnutls_assert ();
628           goto cleanup;
629         }
630
631       if (!matches (&pubkey, data, match))
632         {
633           gnutls_assert ();
634           *verify |= DANE_VERIFY_CERT_DIFFERS;
635         }
636     }
637   else
638     {
639       ret = gnutls_assert_val (DANE_E_UNKNOWN_DANE_DATA);
640       goto cleanup;
641     }
642
643   ret = 0;
644 cleanup:
645   free (pubkey.data);
646   return ret;
647 }
648
649 /**
650  * dane_verify_crt_raw:
651  * @s: A DANE state structure (may be NULL)
652  * @chain: A certificate chain
653  * @chain_size: The size of the chain
654  * @chain_type: The type of the certificate chain
655  * @r: DANE data to check against
656  * @sflags: Flags for the the initialization of @s (if NULL)
657  * @vflags: Verification flags; an OR'ed list of %dane_verify_flags_t.
658  * @verify: An OR'ed list of %dane_verify_status_t.
659  *
660  * This function will verify the given certificate chain against the
661  * CA constrains and/or the certificate available via DANE.
662  * If no information via DANE can be obtained the flag %DANE_VERIFY_NO_DANE_INFO
663  * is set. If a DNSSEC signature is not available for the DANE
664  * record then the verify flag %DANE_VERIFY_NO_DNSSEC_DATA is set.
665  *
666  * Note that the CA constraint only applies for the directly certifying CA
667  * and does not account for long CA chains.
668  *
669  * Due to the many possible options of DANE, there is no single threat
670  * model countered. When notifying the user about DANE verification results
671  * it may be better to mention: DANE verification did not reject the certificate,
672  * rather than mentioning a successful DANE verication.
673  *
674  * If the @q parameter is provided it will be used for caching entries.
675  *
676  * Returns: On success, %DANE_E_SUCCESS (0) is returned, otherwise a
677  *   negative error value.
678  *
679  **/
680 int
681 dane_verify_crt_raw (dane_state_t s,
682                      const gnutls_datum_t * chain, unsigned chain_size,
683                      gnutls_certificate_type_t chain_type,
684                      dane_query_t r,
685                      unsigned int sflags, unsigned int vflags,
686                      unsigned int *verify)
687 {
688   int ret;
689   unsigned checked = 0;
690   unsigned int usage, type, match, idx;
691   gnutls_datum_t data;
692
693   if (chain_type != GNUTLS_CRT_X509)
694     return gnutls_assert_val (DANE_E_INVALID_REQUEST);
695
696   *verify = 0;
697   idx = 0;
698   do
699     {
700       ret = dane_query_data (r, idx++, &usage, &type, &match, &data);
701       if (ret == DANE_E_REQUESTED_DATA_NOT_AVAILABLE)
702         break;
703
704       if (ret < 0)
705         {
706           gnutls_assert ();
707           goto cleanup;
708         }
709
710       if (!(vflags & DANE_VFLAG_ONLY_CHECK_EE_USAGE)
711           && (usage == DANE_CERT_USAGE_LOCAL_CA
712               || usage == DANE_CERT_USAGE_CA))
713         {
714           ret =
715             verify_ca (chain, chain_size, chain_type, type, match, &data,
716                        verify);
717           if (ret < 0)
718             {
719               gnutls_assert ();
720               goto cleanup;
721             }
722           checked = 1;
723         }
724       else if (!(vflags & DANE_VFLAG_ONLY_CHECK_CA_USAGE)
725                && (usage == DANE_CERT_USAGE_LOCAL_EE
726                    || usage == DANE_CERT_USAGE_EE))
727         {
728           ret = verify_ee (&chain[0], chain_type, type, match, &data, verify);
729           if (ret < 0)
730             {
731               gnutls_assert ();
732               goto cleanup;
733             }
734           checked = 1;
735         }
736     }
737   while (1);
738
739   if ((vflags & DANE_VFLAG_FAIL_IF_NOT_CHECKED) && checked == 0)
740     ret = gnutls_assert_val (DANE_E_REQUESTED_DATA_NOT_AVAILABLE);
741   else
742     ret = 0;
743
744 cleanup:
745   return ret;
746 }
747
748
749 /**
750  * dane_verify_crt:
751  * @s: A DANE state structure (may be NULL)
752  * @chain: A certificate chain
753  * @chain_size: The size of the chain
754  * @chain_type: The type of the certificate chain
755  * @hostname: The hostname associated with the chain
756  * @proto: The protocol of the service connecting (e.g. tcp)
757  * @port: The port of the service connecting (e.g. 443)
758  * @sflags: Flags for the the initialization of @s (if NULL)
759  * @vflags: Verification flags; an OR'ed list of %dane_verify_flags_t.
760  * @verify: An OR'ed list of %dane_verify_status_t.
761  *
762  * This function will verify the given certificate chain against the
763  * CA constrains and/or the certificate available via DANE.
764  * If no information via DANE can be obtained the flag %DANE_VERIFY_NO_DANE_INFO
765  * is set. If a DNSSEC signature is not available for the DANE
766  * record then the verify flag %DANE_VERIFY_NO_DNSSEC_DATA is set.
767  *
768  * Note that the CA constraint only applies for the directly certifying CA
769  * and does not account for long CA chains.
770  *
771  * Due to the many possible options of DANE, there is no single threat
772  * model countered. When notifying the user about DANE verification results
773  * it may be better to mention: DANE verification did not reject the certificate,
774  * rather than mentioning a successful DANE verication.
775  *
776  * If the @q parameter is provided it will be used for caching entries.
777  *
778  * Returns: On success, %DANE_E_SUCCESS (0) is returned, otherwise a
779  *   negative error value.
780  *
781  **/
782 int
783 dane_verify_crt (dane_state_t s,
784                  const gnutls_datum_t * chain, unsigned chain_size,
785                  gnutls_certificate_type_t chain_type,
786                  const char *hostname, const char *proto, unsigned int port,
787                  unsigned int sflags, unsigned int vflags,
788                  unsigned int *verify)
789 {
790   dane_state_t _s = NULL;
791   dane_query_t r = NULL;
792   int ret;
793
794   *verify = 0;
795   if (s == NULL)
796     {
797       ret = dane_state_init (&_s, sflags);
798       if (ret < 0)
799         {
800           gnutls_assert ();
801           return ret;
802         }
803     }
804   else
805     _s = s;
806
807   ret = dane_query_tlsa (_s, &r, hostname, proto, port);
808   if (ret < 0)
809     {
810       gnutls_assert ();
811       goto cleanup;
812     }
813   ret = dane_verify_crt_raw (s, chain, chain_size, chain_type,
814                              r, sflags, vflags, verify);
815 cleanup:
816   if (s == NULL)
817     dane_state_deinit (_s);
818   if (r != NULL)
819     dane_query_deinit (r);
820   return ret;
821 }
822
823 /**
824  * dane_verify_session_crt:
825  * @s: A DANE state structure (may be NULL)
826  * @session: A gnutls session
827  * @hostname: The hostname associated with the chain
828  * @proto: The protocol of the service connecting (e.g. tcp)
829  * @port: The port of the service connecting (e.g. 443)
830  * @sflags: Flags for the the initialization of @s (if NULL)
831  * @vflags: Verification flags; should be zero
832  * @verify: An OR'ed list of %dane_verify_status_t.
833  *
834  * This function will verify session's certificate chain against the
835  * CA constrains and/or the certificate available via DANE.
836  * See dane_verify_crt() for more information.
837  *
838  * Returns: On success, %DANE_E_SUCCESS (0) is returned, otherwise a
839  *   negative error value.
840  *
841  **/
842 int
843 dane_verify_session_crt (dane_state_t s,
844                          gnutls_session_t session,
845                          const char *hostname, const char *proto,
846                          unsigned int port, unsigned int sflags,
847                          unsigned int vflags, unsigned int *verify)
848 {
849   const gnutls_datum_t *cert_list;
850   unsigned int cert_list_size = 0;
851   unsigned int type;
852
853   cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
854   if (cert_list_size == 0)
855     {
856       return gnutls_assert_val (DANE_E_NO_CERT);
857     }
858
859   type = gnutls_certificate_type_get (session);
860
861   return dane_verify_crt (s, cert_list, cert_list_size, type, hostname, proto,
862                           port, sflags, vflags, verify);
863 }
864
865 /**
866  * dane_verification_status_print:
867  * @status: The status flags to be printed
868  * @type: The certificate type
869  * @out: Newly allocated datum with (0) terminated string.
870  * @flags: should be zero
871  *
872  * This function will pretty print the status of a verification
873  * process -- eg. the one obtained by dane_verify_crt().
874  *
875  * The output @out needs to be deallocated using gnutls_free().
876  *
877  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
878  *   negative error value.
879  **/
880 int
881 dane_verification_status_print (unsigned int status,
882                                 gnutls_datum_t * out, unsigned int flags)
883 {
884   gnutls_buffer_st str;
885   int ret;
886
887   _gnutls_buffer_init (&str);
888
889   if (status == 0)
890     _gnutls_buffer_append_str (&str, _("Certificate matches. "));
891   else
892     _gnutls_buffer_append_str (&str, _("Verification failed. "));
893
894   if (status & DANE_VERIFY_CA_CONSTRAINTS_VIOLATED)
895     _gnutls_buffer_append_str (&str, _("CA constrains were violated. "));
896
897   if (status & DANE_VERIFY_CERT_DIFFERS)
898     _gnutls_buffer_append_str (&str, _("The certificate differs. "));
899
900   if (status & DANE_VERIFY_NO_DANE_INFO)
901     _gnutls_buffer_append_str (&str, _("There were no DANE information. "));
902
903   ret = _gnutls_buffer_to_datum (&str, out);
904   if (out->size > 0)
905     out->size--;
906
907   return ret;
908 }