17 #include <sys/types.h>
18 #include <sys/socket.h>
22 #include <openssl/ssl.h>
23 #include <openssl/err.h>
24 #include <openssl/x509v3.h>
34 assert(tlsa_owner !=
NULL);
39 buf[0] = (char)(s - 1);
63 if (*tlsa_owner ==
NULL) {
82 unsigned char* digest;
90 len = (size_t)i2d_X509(cert, &buf);
96 xpubkey = X509_get_X509_PUBKEY(cert);
101 epubkey = X509_PUBKEY_get(xpubkey);
105 len = (size_t)i2d_PUBKEY(epubkey, &buf);
112 switch(matching_type) {
122 digest =
LDNS_XMALLOC(
unsigned char, SHA256_DIGEST_LENGTH);
123 if (digest ==
NULL) {
127 (void)
ldns_sha256(buf, (
unsigned int)len, digest);
137 digest =
LDNS_XMALLOC(
unsigned char, SHA512_DIGEST_LENGTH);
138 if (digest ==
NULL) {
142 (void)
ldns_sha512(buf, (
unsigned int)len, digest);
161 ldns_dane_pkix_validate(X509* cert, STACK_OF(X509)* extra_certs,
164 X509_STORE_CTX* vrfy_ctx;
170 vrfy_ctx = X509_STORE_CTX_new();
175 }
else if (X509_STORE_CTX_init(vrfy_ctx, store,
176 cert, extra_certs) != 1) {
179 }
else if (X509_verify_cert(vrfy_ctx) == 1) {
186 X509_STORE_CTX_free(vrfy_ctx);
195 ldns_dane_pkix_validate_and_get_chain(STACK_OF(X509)** chain, X509* cert,
196 STACK_OF(X509)* extra_certs, X509_STORE* store)
199 X509_STORE* empty_store =
NULL;
200 X509_STORE_CTX* vrfy_ctx;
202 assert(chain !=
NULL);
205 store = empty_store = X509_STORE_new();
208 vrfy_ctx = X509_STORE_CTX_new();
211 goto exit_free_empty_store;
213 }
else if (X509_STORE_CTX_init(vrfy_ctx, store,
214 cert, extra_certs) != 1) {
215 goto exit_free_vrfy_ctx;
217 }
else if (X509_verify_cert(vrfy_ctx) == 1) {
224 *chain = X509_STORE_CTX_get1_chain(vrfy_ctx);
230 X509_STORE_CTX_free(vrfy_ctx);
232 exit_free_empty_store:
234 X509_STORE_free(empty_store);
243 ldns_dane_pkix_get_chain(STACK_OF(X509)** chain,
244 X509* cert, STACK_OF(X509)* extra_certs)
247 X509_STORE* empty_store =
NULL;
248 X509_STORE_CTX* vrfy_ctx;
250 assert(chain !=
NULL);
252 empty_store = X509_STORE_new();
254 vrfy_ctx = X509_STORE_CTX_new();
257 goto exit_free_empty_store;
259 }
else if (X509_STORE_CTX_init(vrfy_ctx, empty_store,
260 cert, extra_certs) != 1) {
261 goto exit_free_vrfy_ctx;
263 (void) X509_verify_cert(vrfy_ctx);
264 *chain = X509_STORE_CTX_get1_chain(vrfy_ctx);
271 X509_STORE_CTX_free(vrfy_ctx);
273 exit_free_empty_store:
274 X509_STORE_free(empty_store);
282 ldns_dane_get_nth_cert_from_validation_chain(
283 X509** cert, STACK_OF(X509)* chain,
int n,
bool ca)
285 if (n >= sk_X509_num(chain) || n < 0) {
288 *cert = sk_X509_pop(chain);
291 *cert = sk_X509_pop(chain);
293 if (ca && ! X509_check_ca(*cert)) {
304 ldns_dane_pkix_get_last_self_signed(X509** out_cert,
305 X509* cert, STACK_OF(X509)* extra_certs)
308 X509_STORE* empty_store =
NULL;
309 X509_STORE_CTX* vrfy_ctx;
311 assert(out_cert !=
NULL);
313 empty_store = X509_STORE_new();
315 vrfy_ctx = X509_STORE_CTX_new();
317 goto exit_free_empty_store;
319 }
else if (X509_STORE_CTX_init(vrfy_ctx, empty_store,
320 cert, extra_certs) != 1) {
321 goto exit_free_vrfy_ctx;
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){
328 *out_cert = X509_STORE_CTX_get_current_cert( vrfy_ctx);
334 X509_STORE_CTX_free(vrfy_ctx);
336 exit_free_empty_store:
337 X509_STORE_free(empty_store);
344 X509* cert, STACK_OF(X509)* extra_certs,
345 X509_STORE* pkix_validation_store,
349 STACK_OF(X509)* pkix_validation_chain =
NULL;
351 assert(selected_cert !=
NULL);
352 assert(cert !=
NULL);
359 if (pkix_validation_store ==
NULL) {
360 switch (cert_usage) {
379 switch (cert_usage) {
383 s = ldns_dane_pkix_validate_and_get_chain(
384 &pkix_validation_chain,
386 pkix_validation_store);
387 if (! pkix_validation_chain) {
394 s = ldns_dane_get_nth_cert_from_validation_chain(
395 selected_cert, pkix_validation_chain,
398 sk_X509_pop_free(pkix_validation_chain, X509_free);
405 *selected_cert = cert;
406 return ldns_dane_pkix_validate(cert, extra_certs,
407 pkix_validation_store);
414 s = ldns_dane_pkix_get_last_self_signed(
415 selected_cert, cert, extra_certs);
418 s = ldns_dane_pkix_get_chain(
419 &pkix_validation_chain,
423 ldns_dane_get_nth_cert_from_validation_chain(
424 selected_cert, pkix_validation_chain,
426 }
else if (! pkix_validation_chain) {
429 sk_X509_pop_free(pkix_validation_chain, X509_free);
437 *selected_cert = cert;
458 assert(tlsa !=
NULL);
459 assert(cert !=
NULL);
468 (uint8_t)certificate_usage);
506 ldns_dane_filter_unusable_records(
const ldns_rr_list* tlsas)
558 ldns_dane_match_any_cert_with_data(STACK_OF(X509)* chain,
567 n = (size_t)sk_X509_num(chain);
568 for (i = 0; i < n; i++) {
569 cert = sk_X509_pop(chain);
574 s = ldns_dane_match_cert_with_data(cert,
575 selector, matching_type, data);
593 X509* cert, STACK_OF(X509)* extra_certs,
594 X509_STORE* pkix_validation_store)
598 STACK_OF(X509)* pkix_validation_chain =
NULL;
608 return ldns_dane_pkix_validate(cert, extra_certs,
609 pkix_validation_store);
616 switch (cert_usage) {
618 s = ldns_dane_pkix_validate_and_get_chain(
619 &pkix_validation_chain,
621 pkix_validation_store);
622 if (! pkix_validation_chain) {
634 s = ldns_dane_match_any_cert_with_data(
635 pkix_validation_chain,
636 selector, matching_type, data,
true);
649 s = ldns_dane_match_any_cert_with_data(
650 pkix_validation_chain,
651 selector, matching_type, data,
true);
653 sk_X509_pop_free(pkix_validation_chain, X509_free);
658 s = ldns_dane_match_cert_with_data(cert,
659 selector, matching_type, data);
662 return ldns_dane_pkix_validate(cert, extra_certs,
663 pkix_validation_store);
669 s = ldns_dane_pkix_get_chain(&pkix_validation_chain,
673 s = ldns_dane_match_any_cert_with_data(
674 pkix_validation_chain,
675 selector, matching_type, data,
false);
677 }
else if (! pkix_validation_chain) {
680 sk_X509_pop_free(pkix_validation_chain, X509_free);
685 return ldns_dane_match_cert_with_data(cert,
686 selector, matching_type, data);
698 X509* cert, STACK_OF(X509)* extra_certs,
699 X509_STORE* pkix_validation_store)
705 assert(cert !=
NULL);
708 tlsas = ldns_dane_filter_unusable_records(tlsas);
716 return ldns_dane_pkix_validate(cert, extra_certs,
717 pkix_validation_store);
723 pkix_validation_store);
734 s = (s > ps ? s : ps);
ldns_rdf * ldns_rr_rdf(const ldns_rr *rr, size_t nr)
returns the rdata field member counter.
ldns_rr_list * ldns_rr_list_new()
creates a new rr_list structure.
ldns_rdf * ldns_rr_set_rdf(ldns_rr *rr, const ldns_rdf *f, size_t position)
sets a rdf member, it will be set on the position given.
bool ldns_rr_list_push_rr(ldns_rr_list *rr_list, const ldns_rr *rr)
pushes an rr to an rrlist.
List or Set of Resource Records.
uint8_t ldns_rdf2native_int8(const ldns_rdf *rd)
returns the native uint8_t representation from the rdf.
Exact match on selected content.
#define LDNS_XMALLOC(type, count)
size_t ldns_rdf_size(const ldns_rdf *rd)
returns the size of the rdf.
ldns_rr * ldns_rr_new_frm_type(ldns_rr_type t)
creates a new rr structure, based on the given type.
size_t ldns_rr_rd_count(const ldns_rr *rr)
returns the rd_count of an rr structure.
void ldns_rr_free(ldns_rr *rr)
frees an RR structure
unsigned char * ldns_sha256(unsigned char *data, unsigned int data_len, unsigned char *digest)
Convenience function to digest a fixed block of data at once.
void ldns_rr_list_free(ldns_rr_list *rr_list)
frees an rr_list structure.
ldns_status ldns_dane_create_tlsa_rr(ldns_rr **tlsa, ldns_tlsa_certificate_usage certificate_usage, ldns_tlsa_selector selector, ldns_tlsa_matching_type matching_type, X509 *cert)
Creates a TLSA resource record from the certificate.
void ldns_rdf_free(ldns_rdf *rd)
frees a rdf structure, leaving the data pointer intact.
This module contains base functions for creating and verifying TLSA RR's with PKIX certificates...
Including this file will include all ldns files, and define some lookup tables.
ldns_rdf * ldns_native2rdf_int8(ldns_rdf_type type, uint8_t value)
returns the rdf containing the native uint8_t repr.
uint8_t * ldns_rdf_data(const ldns_rdf *rd)
returns the data of the rdf.
ldns_rr * ldns_rr_list_rr(const ldns_rr_list *rr_list, size_t nr)
returns a specific rr of an rrlist.
#define LDNS_MAX_DOMAINLEN
Maximum length of a complete dname.
ldns_status ldns_dane_cert2rdf(ldns_rdf **rdf, X509 *cert, ldns_tlsa_selector selector, ldns_tlsa_matching_type matching_type)
Creates a LDNS_RDF_TYPE_HEX type rdf based on the binary data choosen by the selector and encoded usi...
Sevice certificate constraint.
Full certificate: the Certificate binary structure as defined in [RFC5280].
unsigned char * ldns_sha512(unsigned char *data, unsigned int data_len, unsigned char *digest)
Convenience function to digest a fixed block of data at once.
SubjectPublicKeyInfo: DER-encoded binary structure as defined in [RFC5280].
ldns_status ldns_dane_verify(ldns_rr_list *tlsas, X509 *cert, STACK_OF(X509)*extra_certs, X509_STORE *pkix_validation_store)
Verify if any of the given TLSA resource records matches the given certificate.
enum ldns_enum_dane_transport ldns_dane_transport
ldns_rdf_type ldns_rdf_get_type(const ldns_rdf *rd)
returns the type of the rdf.
ldns_rr_type ldns_rr_get_type(const ldns_rr *rr)
returns the type of the rr.
ldns_status ldns_dane_create_tlsa_owner(ldns_rdf **tlsa_owner, const ldns_rdf *name, uint16_t port, ldns_dane_transport transport)
Creates a dname consisting of the given name, prefixed by the service port and type of transport: _po...
enum ldns_enum_tlsa_selector ldns_tlsa_selector
ldns_status ldns_dane_verify_rr(const ldns_rr *tlsa_rr, X509 *cert, STACK_OF(X509)*extra_certs, X509_STORE *pkix_validation_store)
Verify if the given TLSA resource record matches the given certificate.
enum ldns_enum_status ldns_status
ldns_rdf * ldns_rdf_new_frm_data(ldns_rdf_type type, size_t size, const void *data)
allocates a new rdf structure and fills it.
ldns_rdf * ldns_rdf_new(ldns_rdf_type type, size_t size, void *data)
allocates a new rdf structure and fills it.
enum ldns_enum_tlsa_matching_type ldns_tlsa_matching_type
Domain issued certificate.
SHA-256 hash of selected content [RFC6234].
Resource record data field.
size_t ldns_rr_list_rr_count(const ldns_rr_list *rr_list)
returns the number of rr's in an rr_list.
enum ldns_enum_tlsa_certificate_usage ldns_tlsa_certificate_usage
SHA-512 hash of selected content [RFC6234].
int ldns_rdf_compare(const ldns_rdf *rd1, const ldns_rdf *rd2)
compares two rdf's on their wire formats.
ldns_status ldns_dane_select_certificate(X509 **selected_cert, X509 *cert, STACK_OF(X509)*extra_certs, X509_STORE *pkix_validation_store, ldns_tlsa_certificate_usage cert_usage, int offset)
Selects the certificate from cert, extra_certs or the pkix_validation_store based on the value of cer...