File Coverage

src/ldns/dane.c
Criterion Covered Total %
statement 0 281 0.0
branch 0 146 0.0
condition n/a
subroutine n/a
pod n/a
total 0 427 0.0


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