Home | History | Annotate | Line # | Download | only in objs
      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