certtool: allow specifying a purpose and a hostname for chain verification
[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 100
40
41 #undef gnutls_assert
42 #undef gnutls_assert_val
43
44 #ifdef DEBUG
45 #define gnutls_assert() fprintf(stderr, "ASSERT: %s: %d\n", __FILE__, __LINE__);
46 #define gnutls_assert_val(x) gnutls_assert_val_int(x, __FILE__, __LINE__)
47 static int gnutls_assert_val_int(int val, const char *file, int line)
48 {
49         fprintf(stderr, "ASSERT: %s: %d\n", file, line);
50         return val;
51 }
52 #else
53 #define gnutls_assert()
54 #define gnutls_assert_val(x) (x)
55 #endif
56
57 struct dane_state_st {
58         struct ub_ctx *ctx;
59         unsigned int flags;
60 };
61
62 struct dane_query_st {
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 dane_query_status(dane_query_t q)
83 {
84         return q->status;
85 }
86
87 /**
88  * dane_query_entries:
89  * @q: The query result structure
90  *
91  * This function will return the number of entries in a query.
92  *
93  * Returns: The number of entries.
94  **/
95 unsigned int dane_query_entries(dane_query_t q)
96 {
97         return q->data_entries;
98 }
99
100 /**
101  * dane_query_data:
102  * @q: The query result structure
103  * @idx: The index of the query response.
104  * @usage: The certificate usage (see %dane_cert_usage_t)
105  * @type: The certificate type (see %dane_cert_type_t)
106  * @match: The DANE matching type (see %dane_match_type_t)
107  * @data: The DANE data.
108  *
109  * This function will provide the DANE data from the query
110  * response.
111  *
112  * Returns: On success, %DANE_E_SUCCESS (0) is returned, otherwise a
113  *   negative error value.
114  **/
115 int
116 dane_query_data(dane_query_t q, unsigned int idx,
117                 unsigned int *usage, unsigned int *type,
118                 unsigned int *match, gnutls_datum_t * data)
119 {
120         if (idx >= q->data_entries)
121                 return
122                     gnutls_assert_val(DANE_E_REQUESTED_DATA_NOT_AVAILABLE);
123
124         if (usage)
125                 *usage = q->usage[idx];
126         if (type)
127                 *type = q->type[idx];
128         if (match)
129                 *match = q->match[idx];
130         if (data) {
131                 data->data = q->data[idx].data;
132                 data->size = q->data[idx].size;
133         }
134
135         return DANE_E_SUCCESS;
136 }
137
138 /**
139  * dane_query_to_raw_tlsa:
140  * @q: The query result structure
141  * @data_entries: Pointer set to the number of entries in the query
142  * @dane_data: Pointer to contain an array of DNS rdata items, terminated with a NULL pointer;
143  *             caller must guarantee that the referenced data remains
144  *             valid until dane_query_deinit() is called.
145  * @dane_data_len: Pointer to contain the length n bytes of the dane_data items
146  * @secure: Pointer set true if the result is validated securely, false if
147  *               validation failed or the domain queried has no security info
148  * @bogus: Pointer set true if the result was not secure due to a security failure
149  *
150  * This function will provide the DANE data from the query
151  * response.
152  *
153  * The pointers dane_data and dane_data_len are allocated with gnutls_malloc()
154  * to contain the data from the query result structure (individual
155  * @dane_data items simply point to the original data and are not allocated separately).
156  * The returned @dane_data are only valid during the lifetime of @q.
157  *
158  * Returns: On success, %DANE_E_SUCCESS (0) is returned, otherwise a
159  *   negative error value.
160  */
161 int
162 dane_query_to_raw_tlsa(dane_query_t q, unsigned int *data_entries,
163                 char ***dane_data, int **dane_data_len, int *secure, int *bogus)
164 {
165         size_t data_sz;
166         char *data_buf;
167         unsigned int idx;
168
169         *data_entries = 0;
170         *dane_data = NULL;
171         *dane_data_len = NULL;
172
173         if (secure) {
174                 if (q->status & DANE_QUERY_DNSSEC_VERIFIED)
175                         *secure = 1;
176                 else
177                         *secure = 0;
178         }
179
180         if (bogus) {
181                 if (q->status & DANE_QUERY_BOGUS)
182                         *bogus = 1;
183                 else
184                         *bogus = 0;
185         }
186
187         /* pack dane_data pointer list followed by dane_data contents */
188         data_sz = sizeof (**dane_data) * (q->data_entries + 1);
189         for (idx = 0; idx < q->data_entries; idx++)
190                 data_sz += 3 + q->data[idx].size;
191
192         *dane_data = gnutls_calloc (1, data_sz);
193         if (*dane_data == NULL)
194                 return DANE_E_MEMORY_ERROR;
195         data_buf = (char *)*dane_data;
196         data_buf += sizeof (**dane_data) * (q->data_entries + 1);
197
198         *dane_data_len = gnutls_calloc (q->data_entries + 1, sizeof (**dane_data_len));
199         if (*dane_data_len == NULL) {
200                 free(*dane_data);
201                 *dane_data = NULL;
202                 return DANE_E_MEMORY_ERROR;
203         }
204
205         for (idx = 0; idx < q->data_entries; idx++) {
206                 (*dane_data)[idx] = data_buf;
207                 (*dane_data)[idx][0] = q->usage[idx];
208                 (*dane_data)[idx][1] = q->type[idx];
209                 (*dane_data)[idx][2] = q->match[idx];
210                 memcpy(&(*dane_data)[idx][3], q->data[idx].data, q->data[idx].size);
211                 (*dane_data_len)[idx] = 3 + q->data[idx].size;
212                 data_buf += 3 + q->data[idx].size;
213         }
214         (*dane_data)[idx] = NULL;
215         (*dane_data_len)[idx] = 0;
216         *data_entries = q->data_entries;
217
218         return DANE_E_SUCCESS;
219 }
220
221 /**
222  * dane_state_init:
223  * @s: The structure to be initialized
224  * @flags: flags from the %dane_state_flags enumeration
225  *
226  * This function will initialize a DANE query structure.
227  *
228  * Returns: On success, %DANE_E_SUCCESS (0) is returned, otherwise a
229  *   negative error value.
230  **/
231 int dane_state_init(dane_state_t * s, unsigned int flags)
232 {
233         struct ub_ctx *ctx;
234         int ret;
235
236         *s = calloc(1, sizeof(struct dane_state_st));
237         if (*s == NULL)
238                 return gnutls_assert_val(DANE_E_MEMORY_ERROR);
239
240         ctx = ub_ctx_create();
241         if (!ctx) {
242                 gnutls_assert();
243                 ret = DANE_E_INITIALIZATION_ERROR;
244                 goto cleanup;
245         }
246         ub_ctx_debugout(ctx, stderr);
247
248         if (!(flags & DANE_F_IGNORE_LOCAL_RESOLVER)) {
249                 if ((ret = ub_ctx_resolvconf(ctx, NULL)) != 0) {
250                         gnutls_assert();
251                         ret = DANE_E_INITIALIZATION_ERROR;
252                         goto cleanup;
253                 }
254
255                 if ((ret = ub_ctx_hosts(ctx, NULL)) != 0) {
256                         gnutls_assert();
257                         ret = DANE_E_INITIALIZATION_ERROR;
258                         goto cleanup;
259                 }
260         }
261
262         /* read public keys for DNSSEC verification */
263         if (!(flags & DANE_F_IGNORE_DNSSEC)) {
264                 if ((ret =
265                      ub_ctx_add_ta_file(ctx,
266                                         (char *) UNBOUND_ROOT_KEY_FILE)) !=
267                     0) {
268                         gnutls_assert();
269                         ret = DANE_E_INITIALIZATION_ERROR;
270                         goto cleanup;
271                 }
272         }
273
274         (*s)->ctx = ctx;
275         (*s)->flags = flags;
276
277         return DANE_E_SUCCESS;
278       cleanup:
279
280         if (ctx)
281                 ub_ctx_delete(ctx);
282         free(*s);
283
284         return ret;
285 }
286
287 /**
288  * dane_state_deinit:
289  * @s: The structure to be deinitialized
290  *
291  * This function will deinitialize a DANE query structure.
292  *
293  **/
294 void dane_state_deinit(dane_state_t s)
295 {
296         ub_ctx_delete(s->ctx);
297         free(s);
298 }
299
300 /**
301  * dane_state_set_dlv_file:
302  * @s: The structure to be deinitialized
303  * @file: The file holding the DLV keys.
304  *
305  * This function will set a file with trusted keys
306  * for DLV  (DNSSEC  Lookaside  Validation).
307  *
308  **/
309 int dane_state_set_dlv_file(dane_state_t s, const char *file)
310 {
311         int ret;
312
313         ret =
314             ub_ctx_set_option(s->ctx, (char *) "dlv-anchor-file:",
315                               (void *) file);
316         if (ret != 0)
317                 return gnutls_assert_val(DANE_E_FILE_ERROR);
318
319         return 0;
320 }
321
322 /**
323  * dane_query_deinit:
324  * @q: The structure to be deinitialized
325  *
326  * This function will deinitialize a DANE query result structure.
327  *
328  **/
329 void dane_query_deinit(dane_query_t q)
330 {
331         if (q->result)
332                 ub_resolve_free(q->result);
333         free(q);
334 }
335
336
337 /**
338  * dane_raw_tlsa:
339  * @s: The DANE state structure
340  * @r: A structure to place the result
341  * @dane_data: array of DNS rdata items, terminated with a NULL pointer;
342  *             caller must guarantee that the referenced data remains
343  *             valid until dane_query_deinit() is called.
344  * @dane_data_len: the length n bytes of the dane_data items
345  * @secure: true if the result is validated securely, false if
346  *               validation failed or the domain queried has no security info
347  * @bogus: if the result was not secure (secure = 0) due to a security failure,
348  *              and the result is due to a security failure, bogus is true.
349  *
350  * This function will fill in the TLSA (DANE) structure from
351  * the given raw DNS record data. The @dane_data must be valid
352  * during the lifetime of the query.
353  *
354  * Returns: On success, %DANE_E_SUCCESS (0) is returned, otherwise a
355  *   negative error value.
356  **/
357 int
358 dane_raw_tlsa(dane_state_t s, dane_query_t * r, char *const *dane_data,
359               const int *dane_data_len, int secure, int bogus)
360 {
361         int ret = DANE_E_SUCCESS;
362         unsigned int i;
363
364         *r = calloc(1, sizeof(struct dane_query_st));
365         if (*r == NULL)
366                 return gnutls_assert_val(DANE_E_MEMORY_ERROR);
367
368         (*r)->data_entries = 0;
369
370         for (i = 0; i < MAX_DATA_ENTRIES; i++) {
371                 if (dane_data[i] == NULL)
372                         break;
373
374                 if (dane_data_len[i] <= 3)
375                         return
376                             gnutls_assert_val
377                             (DANE_E_RECEIVED_CORRUPT_DATA);
378
379                 (*r)->usage[i] = dane_data[i][0];
380                 (*r)->type[i] = dane_data[i][1];
381                 (*r)->match[i] = dane_data[i][2];
382                 (*r)->data[i].data = (void *) &dane_data[i][3];
383                 (*r)->data[i].size = dane_data_len[i] - 3;
384                 (*r)->data_entries++;
385         }
386
387         if (!(s->flags & DANE_F_INSECURE) && !secure) {
388                 if (bogus)
389                         ret = gnutls_assert_val(DANE_E_INVALID_DNSSEC_SIG);
390                 else
391                         ret = gnutls_assert_val(DANE_E_NO_DNSSEC_SIG);
392         }
393
394         /* show security status */
395         if (secure) {
396                 (*r)->status = DANE_QUERY_DNSSEC_VERIFIED;
397         } else if (bogus) {
398                 gnutls_assert();
399                 (*r)->status = DANE_QUERY_BOGUS;
400         } else {
401                 gnutls_assert();
402                 (*r)->status = DANE_QUERY_NO_DNSSEC;
403         }
404
405         return ret;
406 }
407
408
409 /**
410  * dane_query_tlsa:
411  * @s: The DANE state structure
412  * @r: A structure to place the result
413  * @host: The host name to resolve.
414  * @proto: The protocol type (tcp, udp, etc.)
415  * @port: The service port number (eg. 443).
416  *
417  * This function will query the DNS server for the TLSA (DANE)
418  * data for the given host.
419  *
420  * Returns: On success, %DANE_E_SUCCESS (0) is returned, otherwise a
421  *   negative error value.
422  **/
423 int
424 dane_query_tlsa(dane_state_t s, dane_query_t * r, const char *host,
425                 const char *proto, unsigned int port)
426 {
427         char ns[1024];
428         int ret;
429         struct ub_result *result;
430
431         snprintf(ns, sizeof(ns), "_%u._%s.%s", port, proto, host);
432
433         /* query for webserver */
434         ret = ub_resolve(s->ctx, ns, 52, 1, &result);
435         if (ret != 0) {
436                 return gnutls_assert_val(DANE_E_RESOLVING_ERROR);
437         }
438
439 /* show first result */
440         if (!result->havedata) {
441                 ub_resolve_free(result);
442                 return gnutls_assert_val(DANE_E_NO_DANE_DATA);
443         }
444
445         ret =
446             dane_raw_tlsa(s, r, result->data, result->len, result->secure,
447                           result->bogus);
448         if (*r == NULL) {
449                 ub_resolve_free(result);
450                 return ret;
451         }
452         (*r)->result = result;
453         return ret;
454 }
455
456
457 static unsigned int
458 matches(const gnutls_datum_t * raw1, const gnutls_datum_t * raw2,
459         dane_match_type_t match)
460 {
461         uint8_t digest[64];
462         int ret;
463
464         if (match == DANE_MATCH_EXACT) {
465                 if (raw1->size != raw2->size)
466                         return gnutls_assert_val(0);
467
468                 if (memcmp(raw1->data, raw2->data, raw1->size) != 0)
469                         return gnutls_assert_val(0);
470
471                 return 1;
472         } else if (match == DANE_MATCH_SHA2_256) {
473
474                 if (raw2->size != 32)
475                         return gnutls_assert_val(0);
476
477                 ret =
478                     gnutls_hash_fast(GNUTLS_DIG_SHA256, raw1->data,
479                                      raw1->size, digest);
480                 if (ret < 0)
481                         return gnutls_assert_val(0);
482
483                 if (memcmp(digest, raw2->data, 32) != 0)
484                         return gnutls_assert_val(0);
485
486                 return 1;
487         } else if (match == DANE_MATCH_SHA2_512) {
488                 if (raw2->size != 64)
489                         return gnutls_assert_val(0);
490
491                 ret =
492                     gnutls_hash_fast(GNUTLS_DIG_SHA512, raw1->data,
493                                      raw1->size, digest);
494                 if (ret < 0)
495                         return gnutls_assert_val(0);
496
497                 if (memcmp(digest, raw2->data, 64) != 0)
498                         return gnutls_assert_val(0);
499
500                 return 1;
501         }
502
503         return gnutls_assert_val(0);
504 }
505
506 static int
507 crt_to_pubkey(const gnutls_datum_t * raw_crt, gnutls_datum_t * out)
508 {
509         gnutls_pubkey_t pub = NULL;
510         gnutls_x509_crt_t crt = NULL;
511         int ret;
512
513         out->data = NULL;
514
515         ret = gnutls_x509_crt_init(&crt);
516         if (ret < 0)
517                 return gnutls_assert_val(DANE_E_PUBKEY_ERROR);
518
519         ret = gnutls_pubkey_init(&pub);
520         if (ret < 0) {
521                 gnutls_assert();
522                 ret = DANE_E_PUBKEY_ERROR;
523                 goto cleanup;
524         }
525
526         ret = gnutls_x509_crt_import(crt, raw_crt, GNUTLS_X509_FMT_DER);
527         if (ret < 0) {
528                 gnutls_assert();
529                 ret = DANE_E_PUBKEY_ERROR;
530                 goto cleanup;
531         }
532
533         ret = gnutls_pubkey_import_x509(pub, crt, 0);
534         if (ret < 0) {
535                 gnutls_assert();
536                 ret = DANE_E_PUBKEY_ERROR;
537                 goto cleanup;
538         }
539
540         ret = gnutls_pubkey_export2(pub, GNUTLS_X509_FMT_DER, out);
541         if (ret < 0) {
542                 gnutls_assert();
543                 ret = DANE_E_PUBKEY_ERROR;
544                 goto cleanup;
545         }
546
547         ret = 0;
548         goto clean_certs;
549
550       cleanup:
551         free(out->data);
552         out->data = NULL;
553       clean_certs:
554         if (pub)
555                 gnutls_pubkey_deinit(pub);
556         if (crt)
557                 gnutls_x509_crt_deinit(crt);
558
559         return ret;
560 }
561
562 static int
563 verify_ca(const gnutls_datum_t * raw_crt, unsigned raw_crt_size,
564           gnutls_certificate_type_t crt_type,
565           dane_cert_type_t ctype,
566           dane_match_type_t match, gnutls_datum_t * data,
567           unsigned int *verify)
568 {
569         gnutls_datum_t pubkey = { NULL, 0 };
570         int ret, i;
571         unsigned int vstatus = 0;
572         gnutls_x509_crt_t crt = NULL, ca = NULL;
573         unsigned is_ok = 0;
574
575         if (raw_crt_size < 2)
576                 return gnutls_assert_val(DANE_E_INVALID_REQUEST);
577
578         if (ctype == DANE_CERT_X509 && crt_type == GNUTLS_CRT_X509) {
579                 is_ok = 0;
580                 for (i=raw_crt_size-1;i>=1;i--) {
581                         if (matches(&raw_crt[i], data, match)) {
582                                 is_ok = 1;
583                                 break;
584                         }
585                 }
586
587                 if (is_ok == 0) {
588                         gnutls_assert();
589                         *verify |= DANE_VERIFY_CA_CONSTRAINTS_VIOLATED;
590                 }
591
592         } else if (ctype == DANE_CERT_PK && crt_type == GNUTLS_CRT_X509) {
593                 is_ok = 0;
594
595                 for (i=raw_crt_size-1;i>=1;i--) {
596                         ret = crt_to_pubkey(&raw_crt[i], &pubkey);
597                         if (ret < 0) {
598                                 gnutls_assert();
599                                 goto cleanup;
600                         }
601
602                         if (matches(&pubkey, data, match)) {
603                                 is_ok = 1;
604                                 break;
605                         }
606
607                         free(pubkey.data);
608                         pubkey.data = NULL;
609                 }
610
611                 if (is_ok == 0) {
612                         gnutls_assert();
613                         *verify |= DANE_VERIFY_CA_CONSTRAINTS_VIOLATED;
614                 }
615         } else {
616                 ret = gnutls_assert_val(DANE_E_UNKNOWN_DANE_DATA);
617                 goto cleanup;
618         }
619
620         /* check if the certificate chain is actually a chain */
621         ret = gnutls_x509_crt_init(&crt);
622         if (ret < 0) {
623                 ret = gnutls_assert_val(DANE_E_CERT_ERROR);
624                 goto cleanup;
625         }
626
627         ret =
628             gnutls_x509_crt_import(crt, &raw_crt[0], GNUTLS_X509_FMT_DER);
629         if (ret < 0) {
630                 ret = gnutls_assert_val(DANE_E_CERT_ERROR);
631                 goto cleanup;
632         }
633
634         for (i=raw_crt_size-1;i>=1;i--) {
635                 ret = gnutls_x509_crt_init(&ca);
636                 if (ret < 0) {
637                         ret = gnutls_assert_val(DANE_E_CERT_ERROR);
638                         goto cleanup;
639                 }
640
641                 ret = gnutls_x509_crt_import(ca, &raw_crt[i], GNUTLS_X509_FMT_DER);
642                 if (ret < 0) {
643                         ret = gnutls_assert_val(DANE_E_CERT_ERROR);
644                         goto cleanup;
645                 }
646
647                 ret = gnutls_x509_crt_check_issuer(crt, ca);
648                 if (ret != 0)
649                         break;
650
651                 gnutls_x509_crt_deinit(ca);
652                 ca = NULL;
653         }
654
655         if (ca == NULL) {
656                 gnutls_assert();
657                 *verify |= DANE_VERIFY_CA_CONSTRAINTS_VIOLATED;
658         } else {
659                 ret = gnutls_x509_crt_verify(crt, &ca, 1, 0, &vstatus);
660                 if (ret < 0) {
661                         ret = gnutls_assert_val(DANE_E_CERT_ERROR);
662                         goto cleanup;
663                 }
664
665                 if (vstatus != 0)
666                         *verify |= DANE_VERIFY_CA_CONSTRAINTS_VIOLATED;
667         }
668
669         ret = 0;
670       cleanup:
671         free(pubkey.data);
672         if (crt != NULL)
673                 gnutls_x509_crt_deinit(crt);
674         if (ca != NULL)
675                 gnutls_x509_crt_deinit(ca);
676         return ret;
677 }
678
679 static int
680 verify_ee(const gnutls_datum_t * raw_crt,
681           gnutls_certificate_type_t crt_type, dane_cert_type_t ctype,
682           dane_match_type_t match, gnutls_datum_t * data,
683           unsigned int *verify)
684 {
685         gnutls_datum_t pubkey = { NULL, 0 };
686         int ret;
687
688         if (ctype == DANE_CERT_X509 && crt_type == GNUTLS_CRT_X509) {
689
690                 if (!matches(raw_crt, data, match)) {
691                         gnutls_assert();
692                         *verify |= DANE_VERIFY_CERT_DIFFERS;
693                 }
694
695         } else if (ctype == DANE_CERT_PK && crt_type == GNUTLS_CRT_X509) {
696
697                 ret = crt_to_pubkey(raw_crt, &pubkey);
698                 if (ret < 0) {
699                         gnutls_assert();
700                         goto cleanup;
701                 }
702
703                 if (!matches(&pubkey, data, match)) {
704                         gnutls_assert();
705                         *verify |= DANE_VERIFY_CERT_DIFFERS;
706                 }
707         } else {
708                 ret = gnutls_assert_val(DANE_E_UNKNOWN_DANE_DATA);
709                 goto cleanup;
710         }
711
712         ret = 0;
713       cleanup:
714         free(pubkey.data);
715         return ret;
716 }
717
718 #define CHECK_VRET(ret, checked, record_status, status) \
719                         if (ret == DANE_E_UNKNOWN_DANE_DATA) { \
720                                 /* skip that entry */ \
721                                 continue; \
722                         } else if (ret < 0) { \
723                                 gnutls_assert(); \
724                                 goto cleanup; \
725                         } \
726                         checked = 1; \
727                         if (record_status == 0) { \
728                                 status = 0; \
729                                 break; \
730                         } else { \
731                                 status |= record_status; \
732                         }
733
734 /**
735  * dane_verify_crt_raw:
736  * @s: A DANE state structure (may be NULL)
737  * @chain: A certificate chain
738  * @chain_size: The size of the chain
739  * @chain_type: The type of the certificate chain
740  * @r: DANE data to check against
741  * @sflags: Flags for the the initialization of @s (if NULL)
742  * @vflags: Verification flags; an OR'ed list of %dane_verify_flags_t.
743  * @verify: An OR'ed list of %dane_verify_status_t.
744  *
745  * This function will verify the given certificate chain against the
746  * CA constrains and/or the certificate available via DANE.
747  * If no information via DANE can be obtained the flag %DANE_VERIFY_NO_DANE_INFO
748  * is set. If a DNSSEC signature is not available for the DANE
749  * record then the verify flag %DANE_VERIFY_NO_DNSSEC_DATA is set.
750  *
751  * Due to the many possible options of DANE, there is no single threat
752  * model countered. When notifying the user about DANE verification results
753  * it may be better to mention: DANE verification did not reject the certificate,
754  * rather than mentioning a successful DANE verication.
755  *
756  * Note that this function is designed to be run in addition to
757  * PKIX - certificate chain - verification. To be run independently
758  * the %DANE_VFLAG_ONLY_CHECK_EE_USAGE flag should be specified; 
759  * then the function will check whether the key of the peer matches the
760  * key advertized in the DANE entry.
761  *
762  * If the @q parameter is provided it will be used for caching entries.
763  *
764  * Returns: On success, %DANE_E_SUCCESS (0) is returned, otherwise a
765  *   negative error value.
766  *
767  **/
768 int
769 dane_verify_crt_raw(dane_state_t s,
770                     const gnutls_datum_t * chain, unsigned chain_size,
771                     gnutls_certificate_type_t chain_type,
772                     dane_query_t r,
773                     unsigned int sflags, unsigned int vflags,
774                     unsigned int *verify)
775 {
776         int ret;
777         unsigned checked = 0;
778         unsigned int usage, type, match, idx;
779         gnutls_datum_t data;
780
781         if (chain_type != GNUTLS_CRT_X509)
782                 return gnutls_assert_val(DANE_E_INVALID_REQUEST);
783
784         if (chain_size == 0)
785                 return gnutls_assert_val(DANE_E_NO_CERT);
786
787         *verify = 0;
788         idx = 0;
789         do {
790                 unsigned int record_verify = 0;
791
792                 ret =
793                     dane_query_data(r, idx++, &usage, &type, &match,
794                                     &data);
795                 if (ret == DANE_E_REQUESTED_DATA_NOT_AVAILABLE)
796                         break;
797
798                 if (ret < 0) {
799                         gnutls_assert();
800                         goto cleanup;
801                 }
802
803                 if (!(vflags & DANE_VFLAG_ONLY_CHECK_EE_USAGE)
804                     && (usage == DANE_CERT_USAGE_LOCAL_CA
805                         || usage == DANE_CERT_USAGE_CA)) {
806                         ret =
807                             verify_ca(chain, chain_size, chain_type, type,
808                                       match, &data, &record_verify);
809                         CHECK_VRET(ret, checked, record_verify, *verify);
810
811                 } else if (!(vflags & DANE_VFLAG_ONLY_CHECK_CA_USAGE)
812                            && (usage == DANE_CERT_USAGE_LOCAL_EE
813                                || usage == DANE_CERT_USAGE_EE)) {
814                         ret =
815                             verify_ee(&chain[0], chain_type, type, match,
816                                       &data, &record_verify);
817                         CHECK_VRET(ret, checked, record_verify, *verify);
818                 }
819         }
820         while (1);
821
822         if ((vflags & DANE_VFLAG_FAIL_IF_NOT_CHECKED) && checked == 0) {
823                 ret =
824                     gnutls_assert_val(DANE_E_REQUESTED_DATA_NOT_AVAILABLE);
825         } else if (checked == 0) {
826                 *verify |= DANE_VERIFY_UNKNOWN_DANE_INFO;
827         } else {
828                 ret = 0;
829         }
830
831       cleanup:
832         return ret;
833 }
834
835
836 /**
837  * dane_verify_crt:
838  * @s: A DANE state structure (may be NULL)
839  * @chain: A certificate chain
840  * @chain_size: The size of the chain
841  * @chain_type: The type of the certificate chain
842  * @hostname: The hostname associated with the chain
843  * @proto: The protocol of the service connecting (e.g. tcp)
844  * @port: The port of the service connecting (e.g. 443)
845  * @sflags: Flags for the the initialization of @s (if NULL)
846  * @vflags: Verification flags; an OR'ed list of %dane_verify_flags_t.
847  * @verify: An OR'ed list of %dane_verify_status_t.
848  *
849  * This function will verify the given certificate chain against the
850  * CA constrains and/or the certificate available via DANE.
851  * If no information via DANE can be obtained the flag %DANE_VERIFY_NO_DANE_INFO
852  * is set. If a DNSSEC signature is not available for the DANE
853  * record then the verify flag %DANE_VERIFY_NO_DNSSEC_DATA is set.
854  *
855  * Due to the many possible options of DANE, there is no single threat
856  * model countered. When notifying the user about DANE verification results
857  * it may be better to mention: DANE verification did not reject the certificate,
858  * rather than mentioning a successful DANE verication.
859  *
860  * Note that this function is designed to be run in addition to
861  * PKIX - certificate chain - verification. To be run independently
862  * the %DANE_VFLAG_ONLY_CHECK_EE_USAGE flag should be specified; 
863  * then the function will check whether the key of the peer matches the
864  * key advertized in the DANE entry.
865  *
866  * If the @q parameter is provided it will be used for caching entries.
867  *
868  * Returns: On success, %DANE_E_SUCCESS (0) is returned, otherwise a
869  *   negative error value.
870  *
871  **/
872 int
873 dane_verify_crt(dane_state_t s,
874                 const gnutls_datum_t * chain, unsigned chain_size,
875                 gnutls_certificate_type_t chain_type,
876                 const char *hostname, const char *proto, unsigned int port,
877                 unsigned int sflags, unsigned int vflags,
878                 unsigned int *verify)
879 {
880         dane_state_t state = NULL;
881         dane_query_t r = NULL;
882         int ret;
883
884         *verify = 0;
885         if (s == NULL) {
886                 ret = dane_state_init(&state, sflags);
887                 if (ret < 0) {
888                         gnutls_assert();
889                         return ret;
890                 }
891         } else
892                 state = s;
893
894         ret = dane_query_tlsa(state, &r, hostname, proto, port);
895         if (ret < 0) {
896                 gnutls_assert();
897                 goto cleanup;
898         }
899         ret = dane_verify_crt_raw(state, chain, chain_size, chain_type,
900                                   r, sflags, vflags, verify);
901       cleanup:
902         if (state != s)
903                 dane_state_deinit(state);
904         if (r != NULL)
905                 dane_query_deinit(r);
906         return ret;
907 }
908
909 /**
910  * dane_verify_session_crt:
911  * @s: A DANE state structure (may be NULL)
912  * @session: A gnutls session
913  * @hostname: The hostname associated with the chain
914  * @proto: The protocol of the service connecting (e.g. tcp)
915  * @port: The port of the service connecting (e.g. 443)
916  * @sflags: Flags for the the initialization of @s (if NULL)
917  * @vflags: Verification flags; an OR'ed list of %dane_verify_flags_t.
918  * @verify: An OR'ed list of %dane_verify_status_t.
919  *
920  * This function will verify session's certificate chain against the
921  * CA constrains and/or the certificate available via DANE.
922  * See dane_verify_crt() for more information.
923  *
924  * This will not verify the chain for validity; unless the DANE
925  * verification is restricted to end certificates, this must be
926  * be performed separately using gnutls_certificate_verify_peers3().
927  *
928  * Returns: On success, %DANE_E_SUCCESS (0) is returned, otherwise a
929  *   negative error value.
930  *
931  **/
932 int
933 dane_verify_session_crt(dane_state_t s,
934                         gnutls_session_t session,
935                         const char *hostname, const char *proto,
936                         unsigned int port, unsigned int sflags,
937                         unsigned int vflags, unsigned int *verify)
938 {
939         const gnutls_datum_t *cert_list;
940         unsigned int cert_list_size = 0;
941         unsigned int type;
942         int ret;
943
944         cert_list = gnutls_certificate_get_peers(session, &cert_list_size);
945         if (cert_list_size == 0) {
946                 return gnutls_assert_val(DANE_E_NO_CERT);
947         }
948
949         type = gnutls_certificate_type_get(session);
950
951         /* this list may be incomplete, try to get the self-signed CA if any */
952         if (cert_list_size > 0) {
953                 gnutls_datum_t new_cert_list[cert_list_size+1];
954                 gnutls_x509_crt_t crt, ca;
955                 gnutls_certificate_credentials_t sc;
956
957                 ret = gnutls_x509_crt_init(&crt);
958                 if (ret < 0) {
959                         gnutls_assert();
960                         goto failsafe;
961                 }
962
963                 ret = gnutls_x509_crt_import(crt, &cert_list[cert_list_size-1], GNUTLS_X509_FMT_DER);
964                 if (ret < 0) {
965                         gnutls_assert();
966                         gnutls_x509_crt_deinit(crt);
967                         goto failsafe;
968                 }
969
970                 /* if it is already self signed continue normally */
971                 ret = gnutls_x509_crt_check_issuer(crt, crt);
972                 if (ret != 0) {
973                         gnutls_assert();
974                         gnutls_x509_crt_deinit(crt);
975                         goto failsafe;
976                 }
977
978                 /* chain does not finish in a self signed cert, try to obtain the issuer */
979                 ret = gnutls_credentials_get(session, GNUTLS_CRD_CERTIFICATE, (void**)&sc);
980                 if (ret < 0) {
981                         gnutls_assert();
982                         gnutls_x509_crt_deinit(crt);
983                         goto failsafe;
984                 }
985
986                 ret = gnutls_certificate_get_issuer(sc, crt, &ca, 0);
987                 if (ret < 0) {
988                         gnutls_assert();
989                         gnutls_x509_crt_deinit(crt);
990                         goto failsafe;
991                 }
992
993                 /* make the new list */
994                 memcpy(new_cert_list, cert_list, cert_list_size*sizeof(gnutls_datum_t));
995
996                 ret = gnutls_x509_crt_export2(ca, GNUTLS_X509_FMT_DER, &new_cert_list[cert_list_size]);
997                 if (ret < 0) {
998                         gnutls_assert();
999                         gnutls_x509_crt_deinit(crt);
1000                         goto failsafe;
1001                 }
1002
1003                 ret = dane_verify_crt(s, new_cert_list, cert_list_size+1, type,
1004                                hostname, proto, port, sflags, vflags,
1005                                verify);
1006                 if (ret < 0) {
1007                         gnutls_assert();
1008                 }
1009                 gnutls_free(new_cert_list[cert_list_size].data);
1010                 return ret;
1011         }
1012
1013  failsafe:
1014         return dane_verify_crt(s, cert_list, cert_list_size, type,
1015                                hostname, proto, port, sflags, vflags,
1016                                verify);
1017 }
1018
1019 /**
1020  * dane_verification_status_print:
1021  * @status: The status flags to be printed
1022  * @type: The certificate type
1023  * @out: Newly allocated datum with (0) terminated string.
1024  * @flags: should be zero
1025  *
1026  * This function will pretty print the status of a verification
1027  * process -- eg. the one obtained by dane_verify_crt().
1028  *
1029  * The output @out needs to be deallocated using gnutls_free().
1030  *
1031  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1032  *   negative error value.
1033  **/
1034 int
1035 dane_verification_status_print(unsigned int status,
1036                                gnutls_datum_t * out, unsigned int flags)
1037 {
1038         gnutls_buffer_st str;
1039
1040         _gnutls_buffer_init(&str);
1041
1042         if (status == 0)
1043                 _gnutls_buffer_append_str(&str,
1044                                           _("Certificate matches. "));
1045         else
1046                 _gnutls_buffer_append_str(&str,
1047                                           _("Verification failed. "));
1048
1049         if (status & DANE_VERIFY_CA_CONSTRAINTS_VIOLATED)
1050                 _gnutls_buffer_append_str(&str,
1051                                           _
1052                                           ("CA constrains were violated. "));
1053
1054         if (status & DANE_VERIFY_CERT_DIFFERS)
1055                 _gnutls_buffer_append_str(&str,
1056                                           _("The certificate differs. "));
1057
1058         if (status & DANE_VERIFY_NO_DANE_INFO)
1059                 _gnutls_buffer_append_str(&str,
1060                                           _
1061                                           ("There were no DANE information. "));
1062
1063         return _gnutls_buffer_to_datum(&str, out, 1);
1064 }