1 /* 2 * Copyright (c) 2022 Apple Inc. All rights reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * https://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef DNS_OBJ_RR_DNSKEY_H 18 #define DNS_OBJ_RR_DNSKEY_H 19 20 //====================================================================================================================== 21 // MARK: - Headers 22 23 #include "dns_obj.h" 24 #include "dns_obj_crypto.h" 25 #include "dns_common.h" 26 #include <stdint.h> 27 #include <stdbool.h> 28 29 #include "nullability.h" 30 31 //====================================================================================================================== 32 // MARK: - Object Reference Definition 33 34 DNS_OBJECT_SUBKIND_TYPEDEF_OPAQUE_POINTER(rr, dnskey); 35 36 //====================================================================================================================== 37 // MARK: - Object Constants 38 39 // DNSKEY flags 40 // Take from <https://tools.ietf.org/html/rfc4034#section-2.1.1>. 41 #define DNSKEY_FLAG_ZONE_KEY (1U << (15 - 7)) // MSB bit 7 42 #define DNSKEY_FLAG_SECURITY_ENTRY_POINT (1U << (15 - 15)) // MSB bit 15 43 44 // DNSKEY algorithms 45 // Taken from <https://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xhtml>. 46 typedef enum dnskey_algorithm_type { 47 DNSKEY_ALGORITHM_DELETE = 0, 48 DNSKEY_ALGORITHM_RSAMD5 = 1, 49 DNSKEY_ALGORITHM_DH = 2, 50 DNSKEY_ALGORITHM_DSA = 3, 51 // Reserved 4 52 DNSKEY_ALGORITHM_RSASHA1 = 5, 53 DNSKEY_ALGORITHM_DSA_NSEC3_SHA1 = 6, 54 DNSKEY_ALGORITHM_RSASHA1_NSEC3_SHA1 = 7, 55 DNSKEY_ALGORITHM_RSASHA256 = 8, 56 // Reserved 9 57 DNSKEY_ALGORITHM_RSASHA512 = 10, 58 // Reserved 11 59 DNSKEY_ALGORITHM_ECC_GOST = 12, 60 DNSKEY_ALGORITHM_ECDSAP256SHA256 = 13, 61 DNSKEY_ALGORITHM_ECDSAP384SHA384 = 14, 62 DNSKEY_ALGORITHM_ED25519 = 15, 63 DNSKEY_ALGORITHM_ED448 = 16, 64 // Unassigned 17 - 122 65 // Reserved 123 - 251 66 DNSKEY_ALGORITHM_INDIRECT = 252, 67 DNSKEY_ALGORITHM_PRIVATEDNS = 253, 68 DNSKEY_ALGORITHM_PRIVATEOID = 254 69 // Reserved 255 70 } dnskey_algorithm_type_t; 71 72 // DNSKEY protocol field 73 // Taken from <https://tools.ietf.org/html/rfc4034#section-2.1.2>. 74 #define DNSKEY_PROTOCOL_DNSSEC 3 75 76 //====================================================================================================================== 77 // MARK: - Object Methods 78 79 /*! 80 * @brief 81 * Create an DNSKEY resource record object. 82 * 83 * @param name 84 * The name of the DNSKEY resource record in domain name labels. 85 * 86 * @param class 87 * The class of the DNSKEY record. 88 * 89 * @param rdata 90 * The pointer to the rdata of the record, when it is NULL, it is negative response. 91 * 92 * @param rdata_len 93 * The length of the rdata, when <code>rdata</code> is NULL, it should be zero. 94 * 95 * @param allocate 96 * The boolean value to indicate whether to allocate new memory and copy all rdata from the memory region pointed by <code>name</code>, 97 * <code>rdata</code>. If it is false, the caller is required to ensure that <code>name</code> and <code>rdata</code> are always valid during the life time 98 * of this DNSKEY resource record object. 99 * 100 * @param out_error 101 * The pointer to the error value indicates the success of the function call or the error encountered. 102 * 103 * @result 104 * The DNSKEY resource record object created, or NULL if error happens during creation. <code>out_error</code> will be set to the error encountered if it is not NULL. 105 */ 106 dns_obj_rr_dnskey_t NULLABLE 107 dns_obj_rr_dnskey_create(const uint8_t * NONNULL name, uint16_t class, const uint8_t * NONNULL rdata, 108 uint16_t rdata_len, bool allocate, dns_obj_error_t * NULLABLE out_error); 109 110 /*! 111 * @brief 112 * Get the flags of the DNSKEY resource record object. 113 * 114 * @param dnskey 115 * The DNSKEY resource record object. 116 * 117 * @result 118 * The flags of DNSKEY object. 119 */ 120 uint16_t 121 dns_obj_rr_dnskey_get_flags(dns_obj_rr_dnskey_t NONNULL dnskey); 122 123 /*! 124 * @brief 125 * Get the protocol of the DNSKEY resource record object. 126 * 127 * @param dnskey 128 * The DNSKEY resource record object. 129 * 130 * @result 131 * The protocol of DNSKEY object. 132 */ 133 uint8_t 134 dns_obj_rr_dnskey_get_protocol(dns_obj_rr_dnskey_t NONNULL dnskey); 135 136 /*! 137 * @brief 138 * Get the algorithm of the DNSKEY resource record object. 139 * 140 * @param dnskey 141 * The DNSKEY resource record object. 142 * 143 * @result 144 * The algorithm of DNSKEY object. 145 */ 146 uint8_t 147 dns_obj_rr_dnskey_get_algorithm(dns_obj_rr_dnskey_t NONNULL dnskey); 148 149 /*! 150 * @brief 151 * Get the public key contained in the DNSKEY resource record object. 152 * 153 * @param dnskey 154 * The DNSKEY resource record object. 155 * 156 * @result 157 * The public key in bytes. 158 */ 159 const uint8_t * NONNULL 160 dns_obj_rr_dnskey_get_public_key(dns_obj_rr_dnskey_t NONNULL dnskey); 161 162 /*! 163 * @brief 164 * Get the size of the public key in the DNSKEY resource record object. 165 * 166 * @param dnskey 167 * The DNSKEY resource record object. 168 * 169 * @result 170 * The public key size in bytes. 171 */ 172 uint16_t 173 dns_obj_rr_dnskey_get_public_key_size(dns_obj_rr_dnskey_t NONNULL dnskey); 174 175 /*! 176 * @brief 177 * Get the key tag of the public key in the DNSKEY resource record object. 178 * 179 * @param dnskey 180 * The DNSKEY resource record object. 181 * 182 * @result 183 * The key tag of the corresponding public key, which can be used to match RRSIG and DS records. 184 */ 185 uint16_t 186 dns_obj_rr_dnskey_get_key_tag(dns_obj_rr_dnskey_t NONNULL dnskey); 187 188 /*! 189 * @brief 190 * Check if the DNSKEY is a zone key that is used by DNSSEC to validates the signature. 191 * 192 * @param dnskey 193 * The DNSKEY resource record object. 194 * 195 * @result 196 * A boolean value to indicate whether the DNSKEY is a zone key. 197 * 198 * @discussion 199 * If a DNSKEY is not a zone key, then this DNSKEY cannot be used for DNSSEC validation. 200 */ 201 bool 202 dns_obj_rr_dnskey_is_zone_key(dns_obj_rr_dnskey_t NONNULL dnskey); 203 204 /*! 205 * @brief 206 * Check if the DNSKEY is a secure entry point that is used by DNSSEC to validates the signature of the zone signing key, in other words, check if the 207 * DNSKEY contains the public key part of the key signing key. The DS record usually validates the DNSKEY that is a secure entry point. 208 * 209 * @param dnskey 210 * The DNSKEY resource record object. 211 * 212 * @result 213 * A boolean value to indicate whether the DNSKEY is a secure entry point. 214 * 215 * @discussion 216 * The information about whether the DNSKEY is a secure entry point or not must not be used in the process validation. It is provided as a debugging tool. A 217 * DNSKEY that is not a secure entry point can also be used as a key signing key. 218 */ 219 bool 220 dns_obj_rr_dnskey_is_secure_entry_point(dns_obj_rr_dnskey_t NONNULL dnskey); 221 222 /*! 223 * @brief 224 * Check if the algorithm that this DNSKEY resource record object uses is supported by the current implementation. 225 * 226 * @param dnskey 227 * The DNSKEY resource record object. 228 * 229 * @result 230 * A boolean value that indicates whether the DNSKEY uses a supported algorithm. 231 * 232 * @discussion 233 * We decide whether to support a DNSKEY algorithm based on the recommendations from <> 234 */ 235 bool 236 dns_obj_rr_dnskey_has_supported_algorithm(dns_obj_rr_dnskey_t NONNULL dnskey); 237 238 /*! 239 * @brief 240 * Check if the specified DNSKEY resource record object is valid to be used for DNSSEC validation. 241 * 242 * @param dnskey 243 * The DNSKEY resource record object. 244 * 245 * @param out_error 246 * The pointer to the error value indicates the success of the function call or the error that shows why the DNSKEY object is not valid for DNSSEC. 247 * 248 * @result 249 * A boolean value to indicate whether the DNSKEY object can be used for DNSSEC. 250 */ 251 bool 252 dns_obj_rr_dnskey_is_valid_for_dnssec(dns_obj_rr_dnskey_t NONNULL dnskey, dns_obj_error_t * NULLABLE out_error); 253 254 /*! 255 * @brief 256 * Compute the digest of the DNSKEY resource record object based on the specified digest type. 257 * 258 * @param dnskey 259 * The DNSKEY resource record object. 260 * 261 * @param ds_digest_type 262 * The digest type value being specified in the DS resource record. 263 * 264 * @param out_digest 265 * The output buffer that will be filled with the digest computed, its size in bytes must be greater than <code>MAX_DIGEST_OUTPUT_SIZE</code>. 266 * 267 * @param out_digest_size 268 * The output digest size that will be set to the size of the generated digest, if no error occurs. 269 * 270 * @result 271 * DNSSEC_ERROR_NO_ERROR if no error occurs, otherwise, the error code that indicates what went wrong while computing the digest. 272 */ 273 dns_obj_error_t 274 dns_obj_rr_dnskey_compute_digest(dns_obj_rr_dnskey_t NONNULL dnskey, uint8_t ds_digest_type, 275 uint8_t out_digest[static MAX_DIGEST_OUTPUT_SIZE], size_t * NONNULL out_digest_size); 276 277 /*! 278 * @brief 279 * Get the priority of the algorithm used by the DNSKEY algorithm. 280 * 281 * @param algorithm 282 * The algorithm of the DNSKEY resource record. 283 * 284 * @result 285 * The priority of the DNSKEY algorithm, the higher the better. Priority 0 means that the corresponding algorithm is not supported and should not be used. 286 */ 287 uint16_t 288 dns_obj_rr_dnskey_algorithm_get_priority(uint8_t algorithm); 289 290 #endif // DNS_OBJ_RR_DNSKEY_H 291