793005ddcb30f99094af049ce9660694bff25458
[dragonfly.git] / contrib / ldns / dane.c
1 /*
2  * Verify or create TLS authentication with DANE (RFC6698)
3  *
4  * (c) NLnetLabs 2012
5  *
6  * See the file LICENSE for the license.
7  *
8  */
9
10 #include <ldns/config.h>
11
12 #include <ldns/ldns.h>
13 #include <ldns/dane.h>
14
15 #include <unistd.h>
16 #include <stdlib.h>
17 #include <sys/types.h>
18 #include <sys/socket.h>
19 #include <netdb.h>
20
21 #ifdef HAVE_SSL
22 #include <openssl/ssl.h>
23 #include <openssl/err.h>
24 #include <openssl/x509v3.h>
25 #endif
26
27 ldns_status
28 ldns_dane_create_tlsa_owner(ldns_rdf** tlsa_owner, const ldns_rdf* name,
29                 uint16_t port, ldns_dane_transport transport)
30 {
31         char buf[LDNS_MAX_DOMAINLEN];
32         size_t s;
33
34         assert(tlsa_owner != NULL);
35         assert(name != NULL);
36         assert(ldns_rdf_get_type(name) == LDNS_RDF_TYPE_DNAME);
37
38         s = (size_t)snprintf(buf, LDNS_MAX_DOMAINLEN, "X_%d", (int)port);
39         buf[0] = (char)(s - 1);
40
41         switch(transport) {
42         case LDNS_DANE_TRANSPORT_TCP:
43                 s += snprintf(buf + s, LDNS_MAX_DOMAINLEN - s, "\004_tcp");
44                 break;
45         
46         case LDNS_DANE_TRANSPORT_UDP:
47                 s += snprintf(buf + s, LDNS_MAX_DOMAINLEN - s, "\004_udp");
48                 break;
49
50         case LDNS_DANE_TRANSPORT_SCTP:
51                 s += snprintf(buf + s, LDNS_MAX_DOMAINLEN - s, "\005_sctp");
52                 break;
53         
54         default:
55                 return LDNS_STATUS_DANE_UNKNOWN_TRANSPORT;
56         }
57         if (s + ldns_rdf_size(name) > LDNS_MAX_DOMAINLEN) {
58                 return LDNS_STATUS_DOMAINNAME_OVERFLOW;
59         }
60         memcpy(buf + s, ldns_rdf_data(name), ldns_rdf_size(name));
61         *tlsa_owner = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_DNAME,
62                         s + ldns_rdf_size(name), buf);
63         if (*tlsa_owner == NULL) {
64                 return LDNS_STATUS_MEM_ERR;
65         }
66         return LDNS_STATUS_OK;
67 }
68
69
70 #ifdef HAVE_SSL
71 ldns_status
72 ldns_dane_cert2rdf(ldns_rdf** rdf, X509* cert,
73                 ldns_tlsa_selector      selector,
74                 ldns_tlsa_matching_type matching_type)
75 {
76         unsigned char* buf = NULL;
77         size_t len;
78
79         X509_PUBKEY* xpubkey;
80         EVP_PKEY* epubkey;
81
82         unsigned char* digest;
83
84         assert(rdf != NULL);
85         assert(cert != NULL);
86
87         switch(selector) {
88         case LDNS_TLSA_SELECTOR_FULL_CERTIFICATE:
89
90                 len = (size_t)i2d_X509(cert, &buf);
91                 break;
92
93         case LDNS_TLSA_SELECTOR_SUBJECTPUBLICKEYINFO:
94
95 #ifndef S_SPLINT_S
96                 xpubkey = X509_get_X509_PUBKEY(cert);
97 #endif
98                 if (! xpubkey) {
99                         return LDNS_STATUS_SSL_ERR;
100                 }
101                 epubkey = X509_PUBKEY_get(xpubkey);
102                 if (! epubkey) {
103                         return LDNS_STATUS_SSL_ERR;
104                 }
105                 len = (size_t)i2d_PUBKEY(epubkey, &buf);
106                 break;
107         
108         default:
109                 return LDNS_STATUS_DANE_UNKNOWN_SELECTOR;
110         }
111
112         switch(matching_type) {
113         case LDNS_TLSA_MATCHING_TYPE_NO_HASH_USED:
114
115                 *rdf = ldns_rdf_new(LDNS_RDF_TYPE_HEX, len, buf);
116                 
117                 return *rdf ? LDNS_STATUS_OK : LDNS_STATUS_MEM_ERR;
118                 break;
119         
120         case LDNS_TLSA_MATCHING_TYPE_SHA256:
121
122                 digest = LDNS_XMALLOC(unsigned char, SHA256_DIGEST_LENGTH);
123                 if (digest == NULL) {
124                         LDNS_FREE(buf);
125                         return LDNS_STATUS_MEM_ERR;
126                 }
127                 (void) ldns_sha256(buf, (unsigned int)len, digest);
128                 *rdf = ldns_rdf_new(LDNS_RDF_TYPE_HEX, SHA256_DIGEST_LENGTH,
129                                 digest);
130                 LDNS_FREE(buf);
131
132                 return *rdf ? LDNS_STATUS_OK : LDNS_STATUS_MEM_ERR;
133                 break;
134
135         case LDNS_TLSA_MATCHING_TYPE_SHA512:
136
137                 digest = LDNS_XMALLOC(unsigned char, SHA512_DIGEST_LENGTH);
138                 if (digest == NULL) {
139                         LDNS_FREE(buf);
140                         return LDNS_STATUS_MEM_ERR;
141                 }
142                 (void) ldns_sha512(buf, (unsigned int)len, digest);
143                 *rdf = ldns_rdf_new(LDNS_RDF_TYPE_HEX, SHA512_DIGEST_LENGTH,
144                                 digest);
145                 LDNS_FREE(buf);
146
147                 return *rdf ? LDNS_STATUS_OK : LDNS_STATUS_MEM_ERR;
148                 break;
149         
150         default:
151                 LDNS_FREE(buf);
152                 return LDNS_STATUS_DANE_UNKNOWN_MATCHING_TYPE;
153         }
154 }
155
156
157 /* Ordinary PKIX validation of cert (with extra_certs to help)
158  * against the CA's in store
159  */
160 static ldns_status
161 ldns_dane_pkix_validate(X509* cert, STACK_OF(X509)* extra_certs,
162                 X509_STORE* store)
163 {
164         X509_STORE_CTX* vrfy_ctx;
165         ldns_status s;
166
167         if (! store) {
168                 return LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE;
169         }
170         vrfy_ctx = X509_STORE_CTX_new();
171         if (! vrfy_ctx) {
172
173                 return LDNS_STATUS_SSL_ERR;
174
175         } else if (X509_STORE_CTX_init(vrfy_ctx, store,
176                                 cert, extra_certs) != 1) {
177                 s = LDNS_STATUS_SSL_ERR;
178
179         } else if (X509_verify_cert(vrfy_ctx) == 1) {
180
181                 s = LDNS_STATUS_OK;
182
183         } else {
184                 s = LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE;
185         }
186         X509_STORE_CTX_free(vrfy_ctx);
187         return s;
188 }
189
190
191 /* Orinary PKIX validation of cert (with extra_certs to help)
192  * against the CA's in store, but also return the validation chain.
193  */
194 static ldns_status
195 ldns_dane_pkix_validate_and_get_chain(STACK_OF(X509)** chain, X509* cert,
196                 STACK_OF(X509)* extra_certs, X509_STORE* store)
197 {
198         ldns_status s;
199         X509_STORE* empty_store = NULL;
200         X509_STORE_CTX* vrfy_ctx;
201
202         assert(chain != NULL);
203
204         if (! store) {
205                 store = empty_store = X509_STORE_new();
206         }
207         s = LDNS_STATUS_SSL_ERR;
208         vrfy_ctx = X509_STORE_CTX_new();
209         if (! vrfy_ctx) {
210
211                 goto exit_free_empty_store;
212
213         } else if (X509_STORE_CTX_init(vrfy_ctx, store,
214                                         cert, extra_certs) != 1) {
215                 goto exit_free_vrfy_ctx;
216
217         } else if (X509_verify_cert(vrfy_ctx) == 1) {
218
219                 s = LDNS_STATUS_OK;
220
221         } else {
222                 s = LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE;
223         }
224         *chain = X509_STORE_CTX_get1_chain(vrfy_ctx);
225         if (! *chain) {
226                 s = LDNS_STATUS_SSL_ERR;
227         }
228
229 exit_free_vrfy_ctx:
230         X509_STORE_CTX_free(vrfy_ctx);
231
232 exit_free_empty_store:
233         if (empty_store) {
234                 X509_STORE_free(empty_store);
235         }
236         return s;
237 }
238
239
240 /* Return the validation chain that can be build out of cert, with extra_certs.
241  */
242 static ldns_status
243 ldns_dane_pkix_get_chain(STACK_OF(X509)** chain,
244                 X509* cert, STACK_OF(X509)* extra_certs)
245 {
246         ldns_status s;
247         X509_STORE* empty_store = NULL;
248         X509_STORE_CTX* vrfy_ctx;
249
250         assert(chain != NULL);
251
252         empty_store = X509_STORE_new();
253         s = LDNS_STATUS_SSL_ERR;
254         vrfy_ctx = X509_STORE_CTX_new();
255         if (! vrfy_ctx) {
256
257                 goto exit_free_empty_store;
258
259         } else if (X509_STORE_CTX_init(vrfy_ctx, empty_store,
260                                         cert, extra_certs) != 1) {
261                 goto exit_free_vrfy_ctx;
262         }
263         (void) X509_verify_cert(vrfy_ctx);
264         *chain = X509_STORE_CTX_get1_chain(vrfy_ctx);
265         if (! *chain) {
266                 s = LDNS_STATUS_SSL_ERR;
267         } else {
268                 s = LDNS_STATUS_OK;
269         }
270 exit_free_vrfy_ctx:
271         X509_STORE_CTX_free(vrfy_ctx);
272
273 exit_free_empty_store:
274         X509_STORE_free(empty_store);
275         return s;
276 }
277
278
279 /* Pop n+1 certs and return the last popped.
280  */
281 static ldns_status
282 ldns_dane_get_nth_cert_from_validation_chain(
283                 X509** cert, STACK_OF(X509)* chain, int n, bool ca)
284 {
285         if (n >= sk_X509_num(chain) || n < 0) {
286                 return LDNS_STATUS_DANE_OFFSET_OUT_OF_RANGE;
287         }
288         *cert = sk_X509_pop(chain);
289         while (n-- > 0) {
290                 X509_free(*cert);
291                 *cert = sk_X509_pop(chain);
292         }
293         if (ca && ! X509_check_ca(*cert)) {
294                 return LDNS_STATUS_DANE_NON_CA_CERTIFICATE;
295         }
296         return LDNS_STATUS_OK;
297 }
298
299
300 /* Create validation chain with cert and extra_certs and returns the last
301  * self-signed (if present).
302  */
303 static ldns_status
304 ldns_dane_pkix_get_last_self_signed(X509** out_cert,
305                 X509* cert, STACK_OF(X509)* extra_certs)
306 {
307         ldns_status s;
308         X509_STORE* empty_store = NULL;
309         X509_STORE_CTX* vrfy_ctx;
310
311         assert(out_cert != NULL);
312
313         empty_store = X509_STORE_new();
314         s = LDNS_STATUS_SSL_ERR;
315         vrfy_ctx = X509_STORE_CTX_new();
316         if (! vrfy_ctx) {
317                 goto exit_free_empty_store;
318
319         } else if (X509_STORE_CTX_init(vrfy_ctx, empty_store,
320                                         cert, extra_certs) != 1) {
321                 goto exit_free_vrfy_ctx;
322
323         }
324         (void) X509_verify_cert(vrfy_ctx);
325         if (vrfy_ctx->error == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN ||
326             vrfy_ctx->error == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT){
327
328                 *out_cert = X509_STORE_CTX_get_current_cert( vrfy_ctx);
329                 s = LDNS_STATUS_OK;
330         } else {
331                 s = LDNS_STATUS_DANE_PKIX_NO_SELF_SIGNED_TRUST_ANCHOR;
332         }
333 exit_free_vrfy_ctx:
334         X509_STORE_CTX_free(vrfy_ctx);
335
336 exit_free_empty_store:
337         X509_STORE_free(empty_store);
338         return s;
339 }
340
341
342 ldns_status
343 ldns_dane_select_certificate(X509** selected_cert,
344                 X509* cert, STACK_OF(X509)* extra_certs,
345                 X509_STORE* pkix_validation_store,
346                 ldns_tlsa_certificate_usage cert_usage, int offset)
347 {
348         ldns_status s;
349         STACK_OF(X509)* pkix_validation_chain = NULL;
350
351         assert(selected_cert != NULL);
352         assert(cert != NULL);
353
354         /* With PKIX validation explicitely turned off (pkix_validation_store
355          *  == NULL), treat the "CA constraint" and "Service certificate
356          * constraint" the same as "Trust anchor assertion" and "Domain issued
357          * certificate" respectively.
358          */
359         if (pkix_validation_store == NULL) {
360                 switch (cert_usage) {
361
362                 case LDNS_TLSA_USAGE_CA_CONSTRAINT:
363
364                         cert_usage = LDNS_TLSA_USAGE_TRUST_ANCHOR_ASSERTION;
365                         break;
366
367                 case LDNS_TLSA_USAGE_SERVICE_CERTIFICATE_CONSTRAINT:
368
369                         cert_usage = LDNS_TLSA_USAGE_DOMAIN_ISSUED_CERTIFICATE;
370                         break;
371
372                 default:
373                         break;
374                 }
375         }
376
377         /* Now what to do with each Certificate usage...
378          */
379         switch (cert_usage) {
380
381         case LDNS_TLSA_USAGE_CA_CONSTRAINT:
382
383                 s = ldns_dane_pkix_validate_and_get_chain(
384                                 &pkix_validation_chain,
385                                 cert, extra_certs,
386                                 pkix_validation_store);
387                 if (! pkix_validation_chain) {
388                         return s;
389                 }
390                 if (s == LDNS_STATUS_OK) {
391                         if (offset == -1) {
392                                 offset = 0;
393                         }
394                         s = ldns_dane_get_nth_cert_from_validation_chain(
395                                         selected_cert, pkix_validation_chain,
396                                         offset, true);
397                 }
398                 sk_X509_pop_free(pkix_validation_chain, X509_free);
399                 return s;
400                 break;
401
402
403         case LDNS_TLSA_USAGE_SERVICE_CERTIFICATE_CONSTRAINT:
404
405                 *selected_cert = cert;
406                 return ldns_dane_pkix_validate(cert, extra_certs,
407                                 pkix_validation_store);
408                 break;
409
410
411         case LDNS_TLSA_USAGE_TRUST_ANCHOR_ASSERTION:
412
413                 if (offset == -1) {
414                         s = ldns_dane_pkix_get_last_self_signed(
415                                         selected_cert, cert, extra_certs);
416                         return s;
417                 } else {
418                         s = ldns_dane_pkix_get_chain(
419                                         &pkix_validation_chain,
420                                         cert, extra_certs);
421                         if (s == LDNS_STATUS_OK) {
422                                 s =
423                                 ldns_dane_get_nth_cert_from_validation_chain(
424                                         selected_cert, pkix_validation_chain,
425                                         offset, false);
426                         } else if (! pkix_validation_chain) {
427                                 return s;
428                         }
429                         sk_X509_pop_free(pkix_validation_chain, X509_free);
430                         return s;
431                 }
432                 break;
433
434
435         case LDNS_TLSA_USAGE_DOMAIN_ISSUED_CERTIFICATE:
436
437                 *selected_cert = cert;
438                 return LDNS_STATUS_OK;
439                 break;
440         
441         default:
442                 return LDNS_STATUS_DANE_UNKNOWN_CERTIFICATE_USAGE;
443                 break;
444         }
445 }
446
447
448 ldns_status
449 ldns_dane_create_tlsa_rr(ldns_rr** tlsa,
450                 ldns_tlsa_certificate_usage certificate_usage,
451                 ldns_tlsa_selector          selector,
452                 ldns_tlsa_matching_type     matching_type,
453                 X509* cert)
454 {
455         ldns_rdf* rdf;
456         ldns_status s;
457
458         assert(tlsa != NULL);
459         assert(cert != NULL);
460
461         /* create rr */
462         *tlsa = ldns_rr_new_frm_type(LDNS_RR_TYPE_TLSA);
463         if (*tlsa == NULL) {
464                 return LDNS_STATUS_MEM_ERR;
465         }
466
467         rdf = ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8,
468                         (uint8_t)certificate_usage);
469         if (rdf == NULL) {
470                 goto memerror;
471         }
472         (void) ldns_rr_set_rdf(*tlsa, rdf, 0);
473
474         rdf = ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, (uint8_t)selector);
475         if (rdf == NULL) {
476                 goto memerror;
477         }
478         (void) ldns_rr_set_rdf(*tlsa, rdf, 1);
479
480         rdf = ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, (uint8_t)matching_type);
481         if (rdf == NULL) {
482                 goto memerror;
483         }
484         (void) ldns_rr_set_rdf(*tlsa, rdf, 2);
485
486         s = ldns_dane_cert2rdf(&rdf, cert, selector, matching_type);
487         if (s == LDNS_STATUS_OK) {
488                 (void) ldns_rr_set_rdf(*tlsa, rdf, 3);
489                 return LDNS_STATUS_OK;
490         }
491         ldns_rr_free(*tlsa);
492         *tlsa = NULL;
493         return s;
494
495 memerror:
496         ldns_rr_free(*tlsa);
497         *tlsa = NULL;
498         return LDNS_STATUS_MEM_ERR;
499 }
500
501
502 /* Return tlsas that actually are TLSA resource records with known values
503  * for the Certificate usage, Selector and Matching type rdata fields.
504  */
505 static ldns_rr_list*
506 ldns_dane_filter_unusable_records(const ldns_rr_list* tlsas)
507 {
508         size_t i;
509         ldns_rr_list* r = ldns_rr_list_new();
510         ldns_rr* tlsa_rr;
511
512         if (! r) {
513                 return NULL;
514         }
515         for (i = 0; i < ldns_rr_list_rr_count(tlsas); i++) {
516                 tlsa_rr = ldns_rr_list_rr(tlsas, i);
517                 if (ldns_rr_get_type(tlsa_rr) == LDNS_RR_TYPE_TLSA &&
518                     ldns_rr_rd_count(tlsa_rr) == 4 &&
519                     ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 0)) <= 3 &&
520                     ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 1)) <= 1 &&
521                     ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 2)) <= 2) {
522
523                         if (! ldns_rr_list_push_rr(r, tlsa_rr)) {
524                                 ldns_rr_list_free(r);
525                                 return NULL;
526                         }
527                 }
528         }
529         return r;
530 }
531
532
533 /* Return whether cert/selector/matching_type matches data.
534  */
535 static ldns_status
536 ldns_dane_match_cert_with_data(X509* cert, ldns_tlsa_selector selector,
537                 ldns_tlsa_matching_type matching_type, ldns_rdf* data)
538 {
539         ldns_status s;
540         ldns_rdf* match_data;
541
542         s = ldns_dane_cert2rdf(&match_data, cert, selector, matching_type);
543         if (s == LDNS_STATUS_OK) {
544                 if (ldns_rdf_compare(data, match_data) != 0) {
545                         s = LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH;
546                 }
547                 ldns_rdf_free(match_data);
548         }
549         return s;
550 }
551
552
553 /* Return whether any certificate from the chain with selector/matching_type
554  * matches data.
555  * ca should be true if the certificate has to be a CA certificate too.
556  */
557 static ldns_status
558 ldns_dane_match_any_cert_with_data(STACK_OF(X509)* chain,
559                 ldns_tlsa_selector      selector,
560                 ldns_tlsa_matching_type matching_type,
561                 ldns_rdf* data, bool ca)
562 {
563         ldns_status s = LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH;
564         size_t n, i;
565         X509* cert;
566
567         n = (size_t)sk_X509_num(chain);
568         for (i = 0; i < n; i++) {
569                 cert = sk_X509_pop(chain);
570                 if (! cert) {
571                         s = LDNS_STATUS_SSL_ERR;
572                         break;
573                 }
574                 s = ldns_dane_match_cert_with_data(cert,
575                                 selector, matching_type, data);
576                 if (ca && s == LDNS_STATUS_OK && ! X509_check_ca(cert)) {
577                         s = LDNS_STATUS_DANE_NON_CA_CERTIFICATE;
578                 }
579                 X509_free(cert);
580                 if (s != LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH) {
581                         break;
582                 }
583                 /* when s == LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH,
584                  * try to match the next certificate
585                  */
586         }
587         return s;
588 }
589
590
591 ldns_status
592 ldns_dane_verify_rr(const ldns_rr* tlsa_rr,
593                 X509* cert, STACK_OF(X509)* extra_certs,
594                 X509_STORE* pkix_validation_store)
595 {
596         ldns_status s;
597
598         STACK_OF(X509)* pkix_validation_chain = NULL;
599
600         ldns_tlsa_certificate_usage cert_usage;
601         ldns_tlsa_selector          selector;
602         ldns_tlsa_matching_type     matching_type;
603         ldns_rdf*                   data;
604
605         if (! tlsa_rr) {
606                 /* No TLSA, so regular PKIX validation
607                  */
608                 return ldns_dane_pkix_validate(cert, extra_certs,
609                                 pkix_validation_store);
610         }
611         cert_usage    = ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 0));
612         selector      = ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 1));
613         matching_type = ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 2));
614         data          =                      ldns_rr_rdf(tlsa_rr, 3) ;
615
616         switch (cert_usage) {
617         case LDNS_TLSA_USAGE_CA_CONSTRAINT:
618                 s = ldns_dane_pkix_validate_and_get_chain(
619                                 &pkix_validation_chain, 
620                                 cert, extra_certs,
621                                 pkix_validation_store);
622                 if (! pkix_validation_chain) {
623                         return s;
624                 }
625                 if (s == LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE) {
626                         /*
627                          * NO PKIX validation. We still try to match *any*
628                          * certificate from the chain, so we return
629                          * TLSA errors over PKIX errors.
630                          *
631                          * i.e. When the TLSA matches no certificate, we return
632                          * TLSA_DID_NOT_MATCH and not PKIX_DID_NOT_VALIDATE
633                          */
634                         s = ldns_dane_match_any_cert_with_data(
635                                         pkix_validation_chain,
636                                         selector, matching_type, data, true);
637
638                         if (s == LDNS_STATUS_OK) {
639                                 /* A TLSA record did match a cert from the
640                                  * chain, thus the error is failed PKIX
641                                  * validation.
642                                  */
643                                 s = LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE;
644                         }
645
646                 } else if (s == LDNS_STATUS_OK) { 
647                         /* PKIX validated, does the TLSA match too? */
648
649                         s = ldns_dane_match_any_cert_with_data(
650                                         pkix_validation_chain,
651                                         selector, matching_type, data, true);
652                 }
653                 sk_X509_pop_free(pkix_validation_chain, X509_free);
654                 return s;
655                 break;
656
657         case LDNS_TLSA_USAGE_SERVICE_CERTIFICATE_CONSTRAINT:
658                 s = ldns_dane_match_cert_with_data(cert,
659                                 selector, matching_type, data);
660
661                 if (s == LDNS_STATUS_OK) {
662                         return ldns_dane_pkix_validate(cert, extra_certs,
663                                         pkix_validation_store);
664                 }
665                 return s;
666                 break;
667
668         case LDNS_TLSA_USAGE_TRUST_ANCHOR_ASSERTION:
669                 s = ldns_dane_pkix_get_chain(&pkix_validation_chain,
670                                 cert, extra_certs);
671
672                 if (s == LDNS_STATUS_OK) {
673                         s = ldns_dane_match_any_cert_with_data(
674                                         pkix_validation_chain,
675                                         selector, matching_type, data, false);
676
677                 } else if (! pkix_validation_chain) {
678                         return s;
679                 }
680                 sk_X509_pop_free(pkix_validation_chain, X509_free);
681                 return s;
682                 break;
683
684         case LDNS_TLSA_USAGE_DOMAIN_ISSUED_CERTIFICATE:
685                 return ldns_dane_match_cert_with_data(cert,
686                                 selector, matching_type, data);
687                 break;
688
689         default:
690                 break;
691         }
692         return LDNS_STATUS_DANE_UNKNOWN_CERTIFICATE_USAGE;
693 }
694
695
696 ldns_status
697 ldns_dane_verify(ldns_rr_list* tlsas,
698                 X509* cert, STACK_OF(X509)* extra_certs,
699                 X509_STORE* pkix_validation_store)
700 {
701         size_t i;
702         ldns_rr* tlsa_rr;
703         ldns_status s = LDNS_STATUS_OK, ps;
704
705         assert(cert != NULL);
706
707         if (tlsas && ldns_rr_list_rr_count(tlsas) > 0) {
708                 tlsas = ldns_dane_filter_unusable_records(tlsas);
709                 if (! tlsas) {
710                         return LDNS_STATUS_MEM_ERR;
711                 }
712         }
713         if (! tlsas || ldns_rr_list_rr_count(tlsas) == 0) {
714                 /* No TLSA's, so regular PKIX validation
715                  */
716                 return ldns_dane_pkix_validate(cert, extra_certs,
717                                 pkix_validation_store);
718         } else {
719                 for (i = 0; i < ldns_rr_list_rr_count(tlsas); i++) {
720                         tlsa_rr = ldns_rr_list_rr(tlsas, i);
721                         ps = s;
722                         s = ldns_dane_verify_rr(tlsa_rr, cert, extra_certs,
723                                         pkix_validation_store);
724
725                         if (s != LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH &&
726                             s != LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE) {
727
728                                 /* which would be LDNS_STATUS_OK (match)
729                                  * or some fatal error preventing use from
730                                  * trying the next TLSA record.
731                                  */
732                                 break;
733                         }
734                         s = (s > ps ? s : ps); /* prefer PKIX_DID_NOT_VALIDATE
735                                                 * over   TLSA_DID_NOT_MATCH
736                                                 */
737                 }
738                 ldns_rr_list_free(tlsas);
739         }
740         return s;
741 }
742 #endif /* HAVE_SSL */