From 6f17d90364f01c3e81073a9ffb40b0093878c8e2 Mon Sep 17 00:00:00 2001 From: Brian Wellington Date: Thu, 20 Apr 2000 19:51:39 +0000 Subject: [PATCH] Partial support for SIG(0) on incoming messages - works when we have the key and it's marked as secure (that is, when no validator or fetch is needed). --- CHANGES | 2 ++ lib/dns/message.c | 87 +++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 82 insertions(+), 7 deletions(-) diff --git a/CHANGES b/CHANGES index 5d2a284990..1f549467c2 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,6 @@ + 67. [func] Partial support for SIG(0) on incoming messages. + 67. [performance] Allow use of alternate (compile-time supplied) OpenSSL libraries/headers. diff --git a/lib/dns/message.c b/lib/dns/message.c index a892b96e0d..5fd2edc52a 100644 --- a/lib/dns/message.c +++ b/lib/dns/message.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #define DNS_MESSAGE_OPCODE_MASK 0x7800U @@ -1150,6 +1151,8 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, goto cleanup; } msg->sigstart = recstart; + skip_name_search = ISC_TRUE; + skip_type_search = ISC_TRUE; } } else covers = 0; @@ -2239,6 +2242,7 @@ dns_message_signer(dns_message_t *msg, dns_name_t *signer) { dns_rdata_generic_sig_t sig; result = dns_rdataset_first(msg->sig0); + INSIST(result == ISC_R_SUCCESS); dns_rdataset_current(msg->sig0, &rdata); result = dns_rdata_tostruct(&rdata, &sig, msg->mctx); @@ -2276,17 +2280,86 @@ dns_message_signer(dns_message_t *msg, dns_name_t *signer) { isc_result_t dns_message_checksig(dns_message_t *msg, dns_view_t *view) { - isc_buffer_t b; + isc_buffer_t b, msgb; REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(view != NULL); - if (msg->tsigkey == NULL && msg->tsigset == NULL) + if (msg->tsigkey == NULL && msg->tsigset == NULL && msg->sig0 == NULL) return (ISC_R_SUCCESS); - if (msg->saved == NULL) - return (DNS_R_EXPECTEDTSIG); - isc_buffer_init(&b, msg->saved->base, msg->saved->length, + INSIST(msg->saved != NULL); + isc_buffer_init(&msgb, msg->saved->base, msg->saved->length, ISC_BUFFERTYPE_BINARY); - isc_buffer_add(&b, msg->saved->length); - return (dns_view_checksig(view, &b, msg)); + isc_buffer_add(&msgb, msg->saved->length); + if (msg->tsigkey != NULL || msg->tsigset != NULL) + return (dns_view_checksig(view, &msgb, msg)); + else { + dns_rdata_t rdata; + dns_rdata_generic_sig_t sig; + dns_rdataset_t keyset; + isc_result_t result; + + result = dns_rdataset_first(msg->sig0); + INSIST(result == ISC_R_SUCCESS); + dns_rdataset_current(msg->sig0, &rdata); + + result = dns_rdata_tostruct(&rdata, &sig, msg->mctx); + if (result != ISC_R_SUCCESS) + return (result); + + dns_rdataset_init(&keyset); + result = dns_view_simplefind(view, &sig.signer, + dns_rdatatype_key, 0, 0, + ISC_FALSE, &keyset, NULL); + + if (result != ISC_R_SUCCESS) { + /* XXXBEW Should possibly create a fetch here */ + result = DNS_R_KEYUNAUTHORIZED; + goto freesig; + } else if (keyset.trust < dns_trust_secure) { + /* XXXBEW Should call a validator here */ + result = DNS_R_KEYUNAUTHORIZED; + goto freesig; + } + result = dns_rdataset_first(&keyset); + INSIST(result == ISC_R_SUCCESS); + for (; + result == ISC_R_SUCCESS; + result = dns_rdataset_next(&keyset)) + { + dst_key_t *key = NULL; + + dns_rdataset_current(&keyset, &rdata); + isc_buffer_init(&b, rdata.data, rdata.length, + ISC_BUFFERTYPE_BINARY); + isc_buffer_add(&b, rdata.length); + + /* + * XXXBEW should actually pass in the key name, + * but it's not used anyway. + */ + result = dst_key_fromdns("", &b, view->mctx, &key); + if (result != ISC_R_SUCCESS) + continue; + if (dst_key_alg(key) != sig.algorithm || + dst_key_id(key) != sig.keyid || + !(dst_key_proto(key) == DNS_KEYPROTO_DNSSEC || + dst_key_proto(key) == DNS_KEYPROTO_ANY)) + { + dst_key_free(key); + continue; + } + result = dns_dnssec_verifymessage(&msgb, msg, key); + dst_key_free(key); + if (result == ISC_R_SUCCESS) + break; + } + if (result == ISC_R_NOMORE) + result = DNS_R_KEYUNAUTHORIZED; + + freesig: + dns_rdataset_disassociate(&keyset); + dns_rdata_freestruct(&sig); + return (result); + } }