summaryrefslogtreecommitdiff
path: root/source4/dns_server
diff options
context:
space:
mode:
Diffstat (limited to 'source4/dns_server')
-rw-r--r--source4/dns_server/dns_crypto.c37
1 files changed, 34 insertions, 3 deletions
diff --git a/source4/dns_server/dns_crypto.c b/source4/dns_server/dns_crypto.c
index 502887fec88..a8d76a4bb26 100644
--- a/source4/dns_server/dns_crypto.c
+++ b/source4/dns_server/dns_crypto.c
@@ -243,12 +243,14 @@ WERROR dns_sign_tsig(struct dns_server *dns,
time_t current_time = time(NULL);
DATA_BLOB packet_blob, tsig_blob, sig;
uint8_t *buffer = NULL;
+ uint8_t *p = NULL;
size_t buffer_len = 0;
struct dns_server_tkey * tkey = NULL;
struct dns_res_rec *tsig = talloc_zero(mem_ctx, struct dns_res_rec);
struct dns_fake_tsig_rec *check_rec = talloc_zero(mem_ctx,
struct dns_fake_tsig_rec);
+ size_t mac_size = 0;
if (tsig == NULL) {
return WERR_NOMEM;
@@ -298,15 +300,44 @@ WERROR dns_sign_tsig(struct dns_server *dns,
return DNS_ERR(SERVER_FAILURE);
}
- buffer_len = packet_blob.length + tsig_blob.length;
+ if (state->tsig != NULL) {
+ mac_size = state->tsig->rdata.tsig_record.mac_size;
+ }
+
+ buffer_len = mac_size;
+
+ buffer_len += packet_blob.length;
+ if (buffer_len < packet_blob.length) {
+ return WERR_INVALID_PARAM;
+ }
+ buffer_len += tsig_blob.length;
+ if (buffer_len < tsig_blob.length) {
+ return WERR_INVALID_PARAM;
+ }
+
buffer = talloc_zero_array(mem_ctx, uint8_t, buffer_len);
if (buffer == NULL) {
return WERR_NOMEM;
}
- memcpy(buffer, packet_blob.data, packet_blob.length);
- memcpy(buffer+packet_blob.length, tsig_blob.data, tsig_blob.length);
+ p = buffer;
+
+ /*
+ * RFC 2845 "4.2 TSIG on Answers", how to lay out the buffer
+ * that we're going to sign:
+ * 1. MAC of request (if present)
+ * 2. Outgoing packet
+ * 3. TSIG record
+ */
+ if (mac_size > 0) {
+ memcpy(p, state->tsig->rdata.tsig_record.mac, mac_size);
+ p += mac_size;
+ }
+
+ memcpy(p, packet_blob.data, packet_blob.length);
+ p += packet_blob.length;
+ memcpy(p, tsig_blob.data, tsig_blob.length);
status = gensec_sign_packet(tkey->gensec, mem_ctx, buffer, buffer_len,
buffer, buffer_len, &sig);