Home | History | Annotate | Line # | Download | only in dns
      1 /*	$NetBSD: key.c,v 1.10 2025/05/21 14:48:02 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
      5  *
      6  * SPDX-License-Identifier: MPL-2.0
      7  *
      8  * This Source Code Form is subject to the terms of the Mozilla Public
      9  * License, v. 2.0. If a copy of the MPL was not distributed with this
     10  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
     11  *
     12  * See the COPYRIGHT file distributed with this work for additional
     13  * information regarding copyright ownership.
     14  */
     15 
     16 #include <inttypes.h>
     17 #include <stdbool.h>
     18 #include <stddef.h>
     19 #include <stdlib.h>
     20 
     21 #include <isc/mem.h>
     22 #include <isc/region.h>
     23 #include <isc/util.h>
     24 
     25 #include <dns/keyvalues.h>
     26 
     27 #include <dst/dst.h>
     28 
     29 #include "dst_internal.h"
     30 
     31 uint16_t
     32 dst_region_computeid(const isc_region_t *source) {
     33 	uint32_t ac;
     34 	const unsigned char *p;
     35 	int size;
     36 
     37 	REQUIRE(source != NULL);
     38 	REQUIRE(source->length >= 4);
     39 
     40 	p = source->base;
     41 	size = source->length;
     42 
     43 	for (ac = 0; size > 1; size -= 2, p += 2) {
     44 		ac += ((*p) << 8) + *(p + 1);
     45 	}
     46 
     47 	if (size > 0) {
     48 		ac += ((*p) << 8);
     49 	}
     50 	ac += (ac >> 16) & 0xffff;
     51 
     52 	return (uint16_t)(ac & 0xffff);
     53 }
     54 
     55 uint16_t
     56 dst_region_computerid(const isc_region_t *source) {
     57 	uint32_t ac;
     58 	const unsigned char *p;
     59 	int size;
     60 
     61 	REQUIRE(source != NULL);
     62 	REQUIRE(source->length >= 4);
     63 
     64 	p = source->base;
     65 	size = source->length;
     66 
     67 	ac = ((*p) << 8) + *(p + 1);
     68 	ac |= DNS_KEYFLAG_REVOKE;
     69 	for (size -= 2, p += 2; size > 1; size -= 2, p += 2) {
     70 		ac += ((*p) << 8) + *(p + 1);
     71 	}
     72 
     73 	if (size > 0) {
     74 		ac += ((*p) << 8);
     75 	}
     76 	ac += (ac >> 16) & 0xffff;
     77 
     78 	return (uint16_t)(ac & 0xffff);
     79 }
     80 
     81 dns_name_t *
     82 dst_key_name(const dst_key_t *key) {
     83 	REQUIRE(VALID_KEY(key));
     84 	return key->key_name;
     85 }
     86 
     87 unsigned int
     88 dst_key_size(const dst_key_t *key) {
     89 	REQUIRE(VALID_KEY(key));
     90 	return key->key_size;
     91 }
     92 
     93 unsigned int
     94 dst_key_proto(const dst_key_t *key) {
     95 	REQUIRE(VALID_KEY(key));
     96 	return key->key_proto;
     97 }
     98 
     99 unsigned int
    100 dst_key_alg(const dst_key_t *key) {
    101 	REQUIRE(VALID_KEY(key));
    102 	return key->key_alg;
    103 }
    104 
    105 uint32_t
    106 dst_key_flags(const dst_key_t *key) {
    107 	REQUIRE(VALID_KEY(key));
    108 	return key->key_flags;
    109 }
    110 
    111 dns_keytag_t
    112 dst_key_id(const dst_key_t *key) {
    113 	REQUIRE(VALID_KEY(key));
    114 	return key->key_id;
    115 }
    116 
    117 dns_keytag_t
    118 dst_key_rid(const dst_key_t *key) {
    119 	REQUIRE(VALID_KEY(key));
    120 	return key->key_rid;
    121 }
    122 
    123 dns_rdataclass_t
    124 dst_key_class(const dst_key_t *key) {
    125 	REQUIRE(VALID_KEY(key));
    126 	return key->key_class;
    127 }
    128 
    129 const char *
    130 dst_key_directory(const dst_key_t *key) {
    131 	REQUIRE(VALID_KEY(key));
    132 	return key->directory;
    133 }
    134 
    135 bool
    136 dst_key_iszonekey(const dst_key_t *key) {
    137 	REQUIRE(VALID_KEY(key));
    138 
    139 	if ((key->key_flags & DNS_KEYFLAG_OWNERMASK) != DNS_KEYOWNER_ZONE) {
    140 		return false;
    141 	}
    142 	if (key->key_proto != DNS_KEYPROTO_DNSSEC &&
    143 	    key->key_proto != DNS_KEYPROTO_ANY)
    144 	{
    145 		return false;
    146 	}
    147 	return true;
    148 }
    149 
    150 bool
    151 dst_key_isnullkey(const dst_key_t *key) {
    152 	REQUIRE(VALID_KEY(key));
    153 
    154 	if ((key->key_flags & DNS_KEYFLAG_TYPEMASK) != DNS_KEYTYPE_NOKEY) {
    155 		return false;
    156 	}
    157 	if ((key->key_flags & DNS_KEYFLAG_OWNERMASK) != DNS_KEYOWNER_ZONE) {
    158 		return false;
    159 	}
    160 	if (key->key_proto != DNS_KEYPROTO_DNSSEC &&
    161 	    key->key_proto != DNS_KEYPROTO_ANY)
    162 	{
    163 		return false;
    164 	}
    165 	return true;
    166 }
    167 
    168 #define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0)
    169 #define KSK(x)	  ((dst_key_flags(x) & DNS_KEYFLAG_KSK) != 0)
    170 #define ID(x)	  dst_key_id(x)
    171 #define ALG(x)	  dst_key_alg(x)
    172 
    173 bool
    174 dst_key_have_ksk_and_zsk(dst_key_t **keys, unsigned int nkeys, unsigned int i,
    175 			 bool check_offline, bool ksk, bool zsk, bool *have_ksk,
    176 			 bool *have_zsk) {
    177 	bool hksk = ksk;
    178 	bool hzsk = zsk;
    179 	isc_result_t result;
    180 
    181 	REQUIRE(keys != NULL);
    182 
    183 	for (unsigned int j = 0; j < nkeys && !(hksk && hzsk); j++) {
    184 		if (j == i || ALG(keys[i]) != ALG(keys[j])) {
    185 			continue;
    186 		}
    187 		/*
    188 		 * Don't consider inactive keys.
    189 		 */
    190 		if (dst_key_inactive(keys[j])) {
    191 			continue;
    192 		}
    193 		/*
    194 		 * Don't consider offline keys.
    195 		 */
    196 		if (check_offline && !dst_key_isprivate(keys[j])) {
    197 			continue;
    198 		}
    199 		if (REVOKE(keys[j])) {
    200 			continue;
    201 		}
    202 
    203 		if (!hksk) {
    204 			result = dst_key_getbool(keys[j], DST_BOOL_KSK, &hksk);
    205 			if (result != ISC_R_SUCCESS) {
    206 				if (KSK(keys[j])) {
    207 					hksk = true;
    208 				}
    209 			}
    210 		}
    211 		if (!hzsk) {
    212 			result = dst_key_getbool(keys[j], DST_BOOL_ZSK, &hzsk);
    213 			if (result != ISC_R_SUCCESS) {
    214 				if (!KSK(keys[j])) {
    215 					hzsk = dst_key_isprivate(keys[j]);
    216 				}
    217 			}
    218 		}
    219 	}
    220 
    221 	SET_IF_NOT_NULL(have_ksk, hksk);
    222 	SET_IF_NOT_NULL(have_zsk, hzsk);
    223 	return hksk && hzsk;
    224 }
    225 
    226 void
    227 dst_key_setbits(dst_key_t *key, uint16_t bits) {
    228 	unsigned int maxbits;
    229 	REQUIRE(VALID_KEY(key));
    230 	if (bits != 0) {
    231 		RUNTIME_CHECK(dst_key_sigsize(key, &maxbits) == ISC_R_SUCCESS);
    232 		maxbits *= 8;
    233 		REQUIRE(bits <= maxbits);
    234 	}
    235 	key->key_bits = bits;
    236 }
    237 
    238 uint16_t
    239 dst_key_getbits(const dst_key_t *key) {
    240 	REQUIRE(VALID_KEY(key));
    241 	return key->key_bits;
    242 }
    243 
    244 void
    245 dst_key_setttl(dst_key_t *key, dns_ttl_t ttl) {
    246 	REQUIRE(VALID_KEY(key));
    247 	key->key_ttl = ttl;
    248 }
    249 
    250 dns_ttl_t
    251 dst_key_getttl(const dst_key_t *key) {
    252 	REQUIRE(VALID_KEY(key));
    253 	return key->key_ttl;
    254 }
    255 
    256 void
    257 dst_key_setdirectory(dst_key_t *key, const char *dir) {
    258 	if (key->directory != NULL) {
    259 		isc_mem_free(key->mctx, key->directory);
    260 	}
    261 	key->directory = isc_mem_strdup(key->mctx, dir);
    262 }
    263 
    264 /*! \file */
    265