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#ifdef USE_DANE
12
13#include <ldns/ldns.h>
14#include <ldns/dane.h>
15
16#include <unistd.h>
17#include <stdlib.h>
18#include <sys/types.h>
19#ifdef HAVE_SYS_SOCKET_H
20#include <sys/socket.h>
21#endif
22#ifdef HAVE_NETDB_H
23#include <netdb.h>
24#endif
25
26#ifdef HAVE_SSL
27#include <openssl/ssl.h>
28#include <openssl/err.h>
29#include <openssl/x509v3.h>
30#endif
31
32ldns_status
33ldns_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	s = (size_t)snprintf(buf, LDNS_MAX_DOMAINLEN, "X_%d", (int)port);
44	buf[0] = (char)(s - 1);
45
46	switch(transport) {
47	case LDNS_DANE_TRANSPORT_TCP:
48		s += snprintf(buf + s, LDNS_MAX_DOMAINLEN - s, "\004_tcp");
49		break;
50
51	case LDNS_DANE_TRANSPORT_UDP:
52		s += snprintf(buf + s, LDNS_MAX_DOMAINLEN - s, "\004_udp");
53		break;
54
55	case LDNS_DANE_TRANSPORT_SCTP:
56		s += snprintf(buf + s, LDNS_MAX_DOMAINLEN - s, "\005_sctp");
57		break;
58
59	default:
60		return LDNS_STATUS_DANE_UNKNOWN_TRANSPORT;
61	}
62	if (s + ldns_rdf_size(name) > LDNS_MAX_DOMAINLEN) {
63		return LDNS_STATUS_DOMAINNAME_OVERFLOW;
64	}
65	memcpy(buf + s, ldns_rdf_data(name), ldns_rdf_size(name));
66	*tlsa_owner = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_DNAME,
67			s + ldns_rdf_size(name), buf);
68	if (*tlsa_owner == NULL) {
69		return LDNS_STATUS_MEM_ERR;
70	}
71	return LDNS_STATUS_OK;
72}
73
74
75#ifdef HAVE_SSL
76ldns_status
77ldns_dane_cert2rdf(ldns_rdf** rdf, X509* cert,
78		ldns_tlsa_selector      selector,
79		ldns_tlsa_matching_type matching_type)
80{
81	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	switch(selector) {
93	case LDNS_TLSA_SELECTOR_FULL_CERTIFICATE:
94
95		len = (size_t)i2d_X509(cert, &buf);
96		break;
97
98	case LDNS_TLSA_SELECTOR_SUBJECTPUBLICKEYINFO:
99
100#ifndef S_SPLINT_S
101		xpubkey = X509_get_X509_PUBKEY(cert);
102#endif
103		if (! xpubkey) {
104			return LDNS_STATUS_SSL_ERR;
105		}
106		epubkey = X509_PUBKEY_get(xpubkey);
107		if (! epubkey) {
108			return LDNS_STATUS_SSL_ERR;
109		}
110		len = (size_t)i2d_PUBKEY(epubkey, &buf);
111		break;
112
113	default:
114		return LDNS_STATUS_DANE_UNKNOWN_SELECTOR;
115	}
116
117	switch(matching_type) {
118	case LDNS_TLSA_MATCHING_TYPE_NO_HASH_USED:
119
120		*rdf = ldns_rdf_new(LDNS_RDF_TYPE_HEX, len, buf);
121
122		return *rdf ? LDNS_STATUS_OK : LDNS_STATUS_MEM_ERR;
123		break;
124
125	case LDNS_TLSA_MATCHING_TYPE_SHA256:
126
127		digest = LDNS_XMALLOC(unsigned char, LDNS_SHA256_DIGEST_LENGTH);
128		if (digest == NULL) {
129			LDNS_FREE(buf);
130			return LDNS_STATUS_MEM_ERR;
131		}
132		(void) ldns_sha256(buf, (unsigned int)len, digest);
133		*rdf = ldns_rdf_new(LDNS_RDF_TYPE_HEX, LDNS_SHA256_DIGEST_LENGTH,
134				digest);
135		LDNS_FREE(buf);
136
137		return *rdf ? LDNS_STATUS_OK : LDNS_STATUS_MEM_ERR;
138		break;
139
140	case LDNS_TLSA_MATCHING_TYPE_SHA512:
141
142		digest = LDNS_XMALLOC(unsigned char, LDNS_SHA512_DIGEST_LENGTH);
143		if (digest == NULL) {
144			LDNS_FREE(buf);
145			return LDNS_STATUS_MEM_ERR;
146		}
147		(void) ldns_sha512(buf, (unsigned int)len, digest);
148		*rdf = ldns_rdf_new(LDNS_RDF_TYPE_HEX, LDNS_SHA512_DIGEST_LENGTH,
149				digest);
150		LDNS_FREE(buf);
151
152		return *rdf ? LDNS_STATUS_OK : LDNS_STATUS_MEM_ERR;
153		break;
154
155	default:
156		LDNS_FREE(buf);
157		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 */
165static ldns_status
166ldns_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	if (! store) {
173		return LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE;
174	}
175	vrfy_ctx = X509_STORE_CTX_new();
176	if (! vrfy_ctx) {
177
178		return LDNS_STATUS_SSL_ERR;
179
180	} else if (X509_STORE_CTX_init(vrfy_ctx, store,
181				cert, extra_certs) != 1) {
182		s = LDNS_STATUS_SSL_ERR;
183
184	} else if (X509_verify_cert(vrfy_ctx) == 1) {
185
186		s = LDNS_STATUS_OK;
187
188	} else {
189		s = LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE;
190	}
191	X509_STORE_CTX_free(vrfy_ctx);
192	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 */
199static ldns_status
200ldns_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	X509_STORE* empty_store = NULL;
205	X509_STORE_CTX* vrfy_ctx;
206
207	assert(chain != NULL);
208
209	if (! store) {
210		store = empty_store = X509_STORE_new();
211	}
212	s = LDNS_STATUS_SSL_ERR;
213	vrfy_ctx = X509_STORE_CTX_new();
214	if (! vrfy_ctx) {
215
216		goto exit_free_empty_store;
217
218	} else if (X509_STORE_CTX_init(vrfy_ctx, store,
219					cert, extra_certs) != 1) {
220		goto exit_free_vrfy_ctx;
221
222	} else if (X509_verify_cert(vrfy_ctx) == 1) {
223
224		s = LDNS_STATUS_OK;
225
226	} else {
227		s = LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE;
228	}
229	*chain = X509_STORE_CTX_get1_chain(vrfy_ctx);
230	if (! *chain) {
231		s = LDNS_STATUS_SSL_ERR;
232	}
233
234exit_free_vrfy_ctx:
235	X509_STORE_CTX_free(vrfy_ctx);
236
237exit_free_empty_store:
238	if (empty_store) {
239		X509_STORE_free(empty_store);
240	}
241	return s;
242}
243
244
245/* Return the validation chain that can be build out of cert, with extra_certs.
246 */
247static ldns_status
248ldns_dane_pkix_get_chain(STACK_OF(X509)** chain,
249		X509* cert, STACK_OF(X509)* extra_certs)
250{
251	ldns_status s;
252	X509_STORE* empty_store = NULL;
253	X509_STORE_CTX* vrfy_ctx;
254
255	assert(chain != NULL);
256
257	empty_store = X509_STORE_new();
258	s = LDNS_STATUS_SSL_ERR;
259	vrfy_ctx = X509_STORE_CTX_new();
260	if (! vrfy_ctx) {
261
262		goto exit_free_empty_store;
263
264	} else if (X509_STORE_CTX_init(vrfy_ctx, empty_store,
265					cert, extra_certs) != 1) {
266		goto exit_free_vrfy_ctx;
267	}
268	(void) X509_verify_cert(vrfy_ctx);
269	*chain = X509_STORE_CTX_get1_chain(vrfy_ctx);
270	if (! *chain) {
271		s = LDNS_STATUS_SSL_ERR;
272	} else {
273		s = LDNS_STATUS_OK;
274	}
275exit_free_vrfy_ctx:
276	X509_STORE_CTX_free(vrfy_ctx);
277
278exit_free_empty_store:
279	X509_STORE_free(empty_store);
280	return s;
281}
282
283
284/* Pop n+1 certs and return the last popped.
285 */
286static ldns_status
287ldns_dane_get_nth_cert_from_validation_chain(
288		X509** cert, STACK_OF(X509)* chain, int n, bool ca)
289{
290	if (n >= sk_X509_num(chain) || n < 0) {
291		return LDNS_STATUS_DANE_OFFSET_OUT_OF_RANGE;
292	}
293	*cert = sk_X509_pop(chain);
294	while (n-- > 0) {
295		X509_free(*cert);
296		*cert = sk_X509_pop(chain);
297	}
298	if (ca && ! X509_check_ca(*cert)) {
299		return LDNS_STATUS_DANE_NON_CA_CERTIFICATE;
300	}
301	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 */
308static ldns_status
309ldns_dane_pkix_get_last_self_signed(X509** out_cert,
310		X509* cert, STACK_OF(X509)* extra_certs)
311{
312	ldns_status s;
313	X509_STORE* empty_store = NULL;
314	X509_STORE_CTX* vrfy_ctx;
315
316	assert(out_cert != NULL);
317
318	empty_store = X509_STORE_new();
319	s = LDNS_STATUS_SSL_ERR;
320	vrfy_ctx = X509_STORE_CTX_new();
321	if (! vrfy_ctx) {
322		goto exit_free_empty_store;
323
324	} else if (X509_STORE_CTX_init(vrfy_ctx, empty_store,
325					cert, extra_certs) != 1) {
326		goto exit_free_vrfy_ctx;
327
328	}
329	(void) X509_verify_cert(vrfy_ctx);
330	if (vrfy_ctx->error == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN ||
331	    vrfy_ctx->error == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT){
332
333		*out_cert = X509_STORE_CTX_get_current_cert( vrfy_ctx);
334		s = LDNS_STATUS_OK;
335	} else {
336		s = LDNS_STATUS_DANE_PKIX_NO_SELF_SIGNED_TRUST_ANCHOR;
337	}
338exit_free_vrfy_ctx:
339	X509_STORE_CTX_free(vrfy_ctx);
340
341exit_free_empty_store:
342	X509_STORE_free(empty_store);
343	return s;
344}
345
346
347ldns_status
348ldns_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	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	if (pkix_validation_store == NULL) {
365		switch (cert_usage) {
366
367		case LDNS_TLSA_USAGE_CA_CONSTRAINT:
368
369			cert_usage = LDNS_TLSA_USAGE_TRUST_ANCHOR_ASSERTION;
370			break;
371
372		case LDNS_TLSA_USAGE_SERVICE_CERTIFICATE_CONSTRAINT:
373
374			cert_usage = LDNS_TLSA_USAGE_DOMAIN_ISSUED_CERTIFICATE;
375			break;
376
377		default:
378			break;
379		}
380	}
381
382	/* Now what to do with each Certificate usage...
383	 */
384	switch (cert_usage) {
385
386	case LDNS_TLSA_USAGE_CA_CONSTRAINT:
387
388		s = ldns_dane_pkix_validate_and_get_chain(
389				&pkix_validation_chain,
390				cert, extra_certs,
391				pkix_validation_store);
392		if (! pkix_validation_chain) {
393			return s;
394		}
395		if (s == LDNS_STATUS_OK) {
396			if (offset == -1) {
397				offset = 0;
398			}
399			s = ldns_dane_get_nth_cert_from_validation_chain(
400					selected_cert, pkix_validation_chain,
401					offset, true);
402		}
403		sk_X509_pop_free(pkix_validation_chain, X509_free);
404		return s;
405		break;
406
407
408	case LDNS_TLSA_USAGE_SERVICE_CERTIFICATE_CONSTRAINT:
409
410		*selected_cert = cert;
411		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		if (offset == -1) {
419			s = ldns_dane_pkix_get_last_self_signed(
420					selected_cert, cert, extra_certs);
421			return s;
422		} else {
423			s = ldns_dane_pkix_get_chain(
424					&pkix_validation_chain,
425					cert, extra_certs);
426			if (s == LDNS_STATUS_OK) {
427				s =
428				ldns_dane_get_nth_cert_from_validation_chain(
429					selected_cert, pkix_validation_chain,
430					offset, false);
431			} else if (! pkix_validation_chain) {
432				return s;
433			}
434			sk_X509_pop_free(pkix_validation_chain, X509_free);
435			return s;
436		}
437		break;
438
439
440	case LDNS_TLSA_USAGE_DOMAIN_ISSUED_CERTIFICATE:
441
442		*selected_cert = cert;
443		return LDNS_STATUS_OK;
444		break;
445
446	default:
447		return LDNS_STATUS_DANE_UNKNOWN_CERTIFICATE_USAGE;
448		break;
449	}
450}
451
452
453ldns_status
454ldns_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	*tlsa = ldns_rr_new_frm_type(LDNS_RR_TYPE_TLSA);
468	if (*tlsa == NULL) {
469		return LDNS_STATUS_MEM_ERR;
470	}
471
472	rdf = ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8,
473			(uint8_t)certificate_usage);
474	if (rdf == NULL) {
475		goto memerror;
476	}
477	(void) ldns_rr_set_rdf(*tlsa, rdf, 0);
478
479	rdf = ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, (uint8_t)selector);
480	if (rdf == NULL) {
481		goto memerror;
482	}
483	(void) ldns_rr_set_rdf(*tlsa, rdf, 1);
484
485	rdf = ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, (uint8_t)matching_type);
486	if (rdf == NULL) {
487		goto memerror;
488	}
489	(void) ldns_rr_set_rdf(*tlsa, rdf, 2);
490
491	s = ldns_dane_cert2rdf(&rdf, cert, selector, matching_type);
492	if (s == LDNS_STATUS_OK) {
493		(void) ldns_rr_set_rdf(*tlsa, rdf, 3);
494		return LDNS_STATUS_OK;
495	}
496	ldns_rr_free(*tlsa);
497	*tlsa = NULL;
498	return s;
499
500memerror:
501	ldns_rr_free(*tlsa);
502	*tlsa = NULL;
503	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 */
510static ldns_rr_list*
511ldns_dane_filter_unusable_records(const ldns_rr_list* tlsas)
512{
513	size_t i;
514	ldns_rr_list* r = ldns_rr_list_new();
515	ldns_rr* tlsa_rr;
516
517	if (! r) {
518		return NULL;
519	}
520	for (i = 0; i < ldns_rr_list_rr_count(tlsas); i++) {
521		tlsa_rr = ldns_rr_list_rr(tlsas, i);
522		if (ldns_rr_get_type(tlsa_rr) == LDNS_RR_TYPE_TLSA &&
523		    ldns_rr_rd_count(tlsa_rr) == 4 &&
524		    ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 0)) <= 3 &&
525		    ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 1)) <= 1 &&
526		    ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 2)) <= 2) {
527
528			if (! ldns_rr_list_push_rr(r, tlsa_rr)) {
529				ldns_rr_list_free(r);
530				return NULL;
531			}
532		}
533	}
534	return r;
535}
536
537
538/* Return whether cert/selector/matching_type matches data.
539 */
540static ldns_status
541ldns_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	s = ldns_dane_cert2rdf(&match_data, cert, selector, matching_type);
548	if (s == LDNS_STATUS_OK) {
549		if (ldns_rdf_compare(data, match_data) != 0) {
550			s = LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH;
551		}
552		ldns_rdf_free(match_data);
553	}
554	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 */
562static ldns_status
563ldns_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	ldns_status s = LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH;
569	size_t n, i;
570	X509* cert;
571
572	n = (size_t)sk_X509_num(chain);
573	for (i = 0; i < n; i++) {
574		cert = sk_X509_pop(chain);
575		if (! cert) {
576			s = LDNS_STATUS_SSL_ERR;
577			break;
578		}
579		s = ldns_dane_match_cert_with_data(cert,
580				selector, matching_type, data);
581		if (ca && s == LDNS_STATUS_OK && ! X509_check_ca(cert)) {
582			s = LDNS_STATUS_DANE_NON_CA_CERTIFICATE;
583		}
584		X509_free(cert);
585		if (s != LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH) {
586			break;
587		}
588		/* when s == LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH,
589		 * try to match the next certificate
590		 */
591	}
592	return s;
593}
594
595
596ldns_status
597ldns_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	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	if (! tlsa_rr) {
611		/* No TLSA, so regular PKIX validation
612		 */
613		return ldns_dane_pkix_validate(cert, extra_certs,
614				pkix_validation_store);
615	}
616	cert_usage    = ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 0));
617	selector      = ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 1));
618	matching_type = ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 2));
619	data          =                      ldns_rr_rdf(tlsa_rr, 3) ;
620
621	switch (cert_usage) {
622	case LDNS_TLSA_USAGE_CA_CONSTRAINT:
623		s = ldns_dane_pkix_validate_and_get_chain(
624				&pkix_validation_chain,
625				cert, extra_certs,
626				pkix_validation_store);
627		if (! pkix_validation_chain) {
628			return s;
629		}
630		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			s = ldns_dane_match_any_cert_with_data(
640					pkix_validation_chain,
641					selector, matching_type, data, true);
642
643			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				s = LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE;
649			}
650
651		} else if (s == LDNS_STATUS_OK) {
652			/* PKIX validated, does the TLSA match too? */
653
654			s = ldns_dane_match_any_cert_with_data(
655					pkix_validation_chain,
656					selector, matching_type, data, true);
657		}
658		sk_X509_pop_free(pkix_validation_chain, X509_free);
659		return s;
660		break;
661
662	case LDNS_TLSA_USAGE_SERVICE_CERTIFICATE_CONSTRAINT:
663		s = ldns_dane_match_cert_with_data(cert,
664				selector, matching_type, data);
665
666		if (s == LDNS_STATUS_OK) {
667			return ldns_dane_pkix_validate(cert, extra_certs,
668					pkix_validation_store);
669		}
670		return s;
671		break;
672
673	case LDNS_TLSA_USAGE_TRUST_ANCHOR_ASSERTION:
674		s = ldns_dane_pkix_get_chain(&pkix_validation_chain,
675				cert, extra_certs);
676
677		if (s == LDNS_STATUS_OK) {
678			s = ldns_dane_match_any_cert_with_data(
679					pkix_validation_chain,
680					selector, matching_type, data, false);
681
682		} else if (! pkix_validation_chain) {
683			return s;
684		}
685		sk_X509_pop_free(pkix_validation_chain, X509_free);
686		return s;
687		break;
688
689	case LDNS_TLSA_USAGE_DOMAIN_ISSUED_CERTIFICATE:
690		return ldns_dane_match_cert_with_data(cert,
691				selector, matching_type, data);
692		break;
693
694	default:
695		break;
696	}
697	return LDNS_STATUS_DANE_UNKNOWN_CERTIFICATE_USAGE;
698}
699
700
701ldns_status
702ldns_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	ldns_status s = LDNS_STATUS_OK, ps;
709
710	assert(cert != NULL);
711
712	if (tlsas && ldns_rr_list_rr_count(tlsas) > 0) {
713		tlsas = ldns_dane_filter_unusable_records(tlsas);
714		if (! tlsas) {
715			return LDNS_STATUS_MEM_ERR;
716		}
717	}
718	if (! tlsas || ldns_rr_list_rr_count(tlsas) == 0) {
719		/* No TLSA's, so regular PKIX validation
720		 */
721		return ldns_dane_pkix_validate(cert, extra_certs,
722				pkix_validation_store);
723	} else {
724		for (i = 0; i < ldns_rr_list_rr_count(tlsas); i++) {
725			tlsa_rr = ldns_rr_list_rr(tlsas, i);
726			ps = s;
727			s = ldns_dane_verify_rr(tlsa_rr, cert, extra_certs,
728					pkix_validation_store);
729
730			if (s != LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH &&
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				break;
738			}
739			s = (s > ps ? s : ps); /* prefer PKIX_DID_NOT_VALIDATE
740						* over   TLSA_DID_NOT_MATCH
741						*/
742		}
743		ldns_rr_list_free(tlsas);
744	}
745	return s;
746}
747#endif /* HAVE_SSL */
748#endif /* USE_DANE */
749