/** * Copyright (C) 2024 Graham Leggett * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ /* * redwax_ldns - DNS handling routines. * */ #include #include "config.h" #include "redwax-tool.h" #include "redwax_util.h" #if HAVE_LDNS_LDNS_H #include module ldns_module; static apr_status_t redwax_ldns_initialise(redwax_tool_t *r) { return OK; } static apr_status_t redwax_ldns_tlsa_metadata_data(redwax_tool_t *r, redwax_metadata_t *m, const redwax_certificate_t *cert, ldns_tlsa_selector selector, ldns_tlsa_matching_type matching_type, X509 *x) { ldns_rr* tlsa; ldns_output_format_storage fmt_storage; ldns_output_format *fmt = ldns_output_format_init(&fmt_storage); fmt->flags |= LDNS_FMT_SHORT; if (LDNS_STATUS_OK == ldns_dane_create_tlsa_rr(&tlsa, LDNS_TLSA_USAGE_PKIX_EE, selector, matching_type, x)) { ldns_buffer* buf = ldns_buffer_new(LDNS_MAX_PACKETLEN); char* str; ldns_status s; ldns_buffer_clear(buf); if (ldns_rr_rd_count(tlsa) > 3) { s = ldns_rdf2buffer_str(buf, ldns_rr_rdf(tlsa, 3)); if (s != LDNS_STATUS_OK) { redwax_print_error(r, "metadata-out: TLSA: %s\n", ldns_get_errorstr_by_id(s)); ldns_buffer_free(buf); return APR_EINVAL; } } str = ldns_buffer_export2str(buf); ldns_buffer_free(buf); switch (matching_type) { case LDNS_TLSA_MATCHING_TYPE_FULL: redwax_metadata_push_object(m, "Full", 0); break; case LDNS_TLSA_MATCHING_TYPE_SHA2_256: redwax_metadata_push_object(m, "SHA2-256", 0); break; case LDNS_TLSA_MATCHING_TYPE_SHA2_512: redwax_metadata_push_object(m, "SHA2-512", 0); break; case LDNS_TLSA_MATCHING_TYPE_PRIVMATCH: redwax_metadata_push_object(m, "PrivMatch", 0); break; } if (cert->common.category == REDWAX_CERTIFICATE_END_ENTITY) { redwax_metadata_add_string(m, "PKIX-EE", apr_psprintf(r->pool, "%d %d %d", LDNS_TLSA_USAGE_PKIX_EE, selector, matching_type)); redwax_metadata_add_string(m, "DANE-EE", apr_psprintf(r->pool, "%d %d %d", LDNS_TLSA_USAGE_DANE_EE, selector, matching_type)); } else { redwax_metadata_add_string(m, "PKIX-TA", apr_psprintf(r->pool, "%d %d %d", LDNS_TLSA_USAGE_PKIX_TA, selector, matching_type)); redwax_metadata_add_string(m, "DANE-TA", apr_psprintf(r->pool, "%d %d %d", LDNS_TLSA_USAGE_DANE_TA, selector, matching_type)); } redwax_metadata_add_string(m, "CertificateAssociationData", apr_pstrdup(r->pool, str)); redwax_metadata_pop_object(m); LDNS_FREE(str); } else { return APR_EINVAL; } return APR_SUCCESS; } static apr_status_t redwax_ldns_add_tlsa_metadata(redwax_tool_t *r, redwax_metadata_t *m, const redwax_certificate_t *cert) { const unsigned char *der = cert->der; X509 *x = d2i_X509(NULL, &der, cert->len); if (!x) { return APR_EINVAL; } redwax_metadata_push_object(m, "TLSA", 0); redwax_metadata_push_object(m, "Cert", 0); redwax_ldns_tlsa_metadata_data(r, m, cert, LDNS_TLSA_SELECTOR_CERT, LDNS_TLSA_MATCHING_TYPE_FULL, x); redwax_ldns_tlsa_metadata_data(r, m, cert, LDNS_TLSA_SELECTOR_CERT, LDNS_TLSA_MATCHING_TYPE_SHA2_256, x); redwax_ldns_tlsa_metadata_data(r, m, cert, LDNS_TLSA_SELECTOR_CERT, LDNS_TLSA_MATCHING_TYPE_SHA2_512, x); redwax_metadata_pop_object(m); redwax_metadata_push_object(m, "SPKI", 0); redwax_ldns_tlsa_metadata_data(r, m, cert, LDNS_TLSA_SELECTOR_SPKI, LDNS_TLSA_MATCHING_TYPE_FULL, x); redwax_ldns_tlsa_metadata_data(r, m, cert, LDNS_TLSA_SELECTOR_SPKI, LDNS_TLSA_MATCHING_TYPE_SHA2_256, x); redwax_ldns_tlsa_metadata_data(r, m, cert, LDNS_TLSA_SELECTOR_SPKI, LDNS_TLSA_MATCHING_TYPE_SHA2_512, x); redwax_metadata_pop_object(m); redwax_metadata_pop_object(m); return OK; } void redwax_add_default_ldns_hooks() { rt_hook_initialise(redwax_ldns_initialise, NULL, NULL, APR_HOOK_MIDDLE); rt_hook_add_dns_metadata(redwax_ldns_add_tlsa_metadata, NULL, NULL, APR_HOOK_MIDDLE); } #else void redwax_add_default_ldns_hooks() { } #endif REDWAX_DECLARE_MODULE(ldns) = { STANDARD_MODULE_STUFF, redwax_add_default_ldns_hooks /* register hooks */ };