/* * Copyright (c) 2021 Apple Inc. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef RDATA_PARSER_H #define RDATA_PARSER_H //====================================================================================================================== // MARK: - Headers #include #include #include "nullability.h" //====================================================================================================================== // MARK: - CNAME Parser /*! * @brief * Get the canonical name of the CNAME record owner specified in the rdata. * * @param rdata * The pointer to the rdata of the CNAME record. * * @result * The canonical name in domain name labels. */ const uint8_t * NONNULL rdata_parser_cname_get_canonical_name(const uint8_t * NONNULL rdata); /*! * @brief * Check if the rdata format of the CNAME is valid or not, by checking the minimal length of the CNAME member. * * @param rdata * The pointer to the rdata of the CNAME record. * * @param rdata_len * The length of the rdata. * * @result * True if the rdata passes the check, otherwise, false. * * @discussion * Note that the rdata must not have the compression pointer, or the validation would fail, because we need the expanded uncompressed RR data to to * DNSSEC validation. The caller of the function should already expand all compression pointers in the record before calling it. */ bool rdata_parser_cname_check_validity(const uint8_t * NONNULL rdata, uint16_t rdata_len); //====================================================================================================================== // MARK: - SOA Parser /*! * @brief * Get the minimum TTL in the SOA record. * * @param rdata * The pointer to the rdata of the SOA record. * * @result * The minimum TTL specified by the SOA record in seconds. */ uint32_t rdata_parser_soa_get_minimum_ttl(const uint8_t * NONNULL rdata); /*! * @brief * Check if the rdata format of the SOA is valid or not, by checking the minimal length of the SOA members. * * @param rdata * The pointer to the rdata of the SOA record. * * @param rdata_len * The length of the rdata. * * @result * True if the rdata passes the check, otherwise, false. * * @discussion * Note that the rdata must not have the compression pointer, or the validation would fail, because we need the expanded uncompressed RR data to to * DNSSEC validation. The caller of the function should already expand all compression pointers in the record before calling it. */ bool rdata_parser_soa_check_validity(const uint8_t * NONNULL rdata, uint16_t rdata_len); //====================================================================================================================== // MARK: - SRV Parser uint16_t rdata_parser_srv_get_priority(const uint8_t * NONNULL rdata); uint16_t rdata_parser_srv_get_weight(const uint8_t * NONNULL rdata); uint16_t rdata_parser_srv_get_port(const uint8_t * NONNULL rdata); const uint8_t * NONNULL rdata_parser_srv_get_target(const uint8_t * NONNULL rdata); bool rdata_parser_srv_check_validity(const uint8_t * NONNULL rdata, uint16_t rdata_len); //====================================================================================================================== // MARK: - NSEC Parser /*! * @brief * Get the next domain name of the NSEC record. * * @param rdata * The pointer to the rdata of the NSEC record. * * @result * The next domain name of the NSEC record in domain name labels format. */ const uint8_t * NONNULL rdata_parser_nsec_get_next_domain_name(const uint8_t * NONNULL rdata); /*! * @brief * Get the type bit maps of the NSEC record. * * @param rdata * The pointer to the rdata of the NSEC record. * * @param out_type_bit_maps_len * The pointer to the type bit maps length value being returned for the returned type bit maps. * * @result * The type bit maps that shows what types of DNS record is covered by the current NSEC. */ const uint8_t * NULLABLE rdata_parser_nsec_get_type_bit_maps(const uint8_t * NONNULL rdata, uint16_t rdata_len, uint16_t * NONNULL out_type_bit_maps_len); /*! * @brief * Check if the rdata format of the NSEC is valid or not, by checking the minimal length of the NSEC members. * * @param rdata * The pointer to the rdata of the NSEC record. * * @param rdata_len * The length of the rdata. * * @result * True if the rdata passes the check, otherwise, false. */ bool rdata_parser_nsec_check_validity(const uint8_t * NONNULL rdata, uint16_t rdata_len); /*! * @brief * Check if the specified DNS type is covered by the type bit maps. * * @param maps * The pointer to the type bit maps of NSEC or NSEC3 record. * * @param maps_len * The length of the type bit maps. * * @param type * The DNS type to be checked. * * @result * The boolean value indicates that whether the type bit maps covers the specified DNS type. */ bool rdata_parser_type_bit_maps_cover_dns_type(const uint8_t * NONNULL maps, uint16_t maps_len, uint16_t type); //====================================================================================================================== // MARK: - DS Parser /*! * @brief * Get the key tag from the DS rdata. * * @param rdata * The pointer to the DS rdata bytes. * * @result * The key tag that can be used to match a DNSKEY. */ uint16_t rdata_parser_ds_get_key_tag(const uint8_t * NONNULL rdata); /*! * @brief * Get the algorithm of the DNSKEY from the DS rdata. * * @param rdata * The pointer to the DS rdata bytes. * * @result * The algorithm of the corresponding DNSKEY matched by this DS record. */ uint8_t rdata_parser_ds_get_algorithm(const uint8_t * NONNULL rdata); /*! * @brief * Get the digest type from the DS rdata. * * @param rdata * The pointer to the DS rdata bytes. * * @result * The digest type that DS record uses to generate the digest. */ uint8_t rdata_parser_ds_get_digest_type(const uint8_t * NONNULL rdata); /*! * @brief * Get the digest in bytes from the DS rdata * * @param rdata * The pointer to the DS rdata bytes. * * @result * The digest of the corresponding DNSKEY record for this DS record. */ const uint8_t * NONNULL rdata_parser_ds_get_digest(const uint8_t * NONNULL rdata); /*! * @brief * Get the length of the digest contained in the DS record. * * @param rdata_len * The length of the DS rdata, in bytes. * * @result * The length of the digest, in bytes. */ uint16_t rdata_parser_ds_get_digest_length(uint16_t rdata_len); /*! * @brief * Check if the rdata with the length is a valid rdata for DS record. * * @param rdata * The pointer to the DS rdata bytes. * * @param rdata_len * The length of the DS rdata, in bytes. * * @result * True if the rdata is a valid DS rdata format, otherwise, false. */ bool rdata_parser_ds_check_validity(const uint8_t * NONNULL rdata, uint16_t rdata_len); //====================================================================================================================== // MARK: - RRSIG Parser /*! * @brief * Get the DNS type covered by the RRSIG record. * * @param rdata * The pointer to the rdata of the RRSIG record. * * @result * The DNS type covered. */ uint16_t rdata_parser_rrsig_get_type_covered(const uint8_t * NONNULL rdata); /*! * @brief * Get the algorithm used by the DNSKEY to generate the current RRSIG record. * * @param rdata * The pointer to the rdata of the RRSIG record. * * @result * The algorithm of the DNSKEY. */ uint8_t rdata_parser_rrsig_get_algorithm(const uint8_t * NONNULL rdata); /*! * @brief * Get the number of uncompressed domain name labels in the RRSIG record (excluding the "*" wildcard matching). * * @param rdata * The pointer to the rdata of the RRSIG record record. * * @result * The number of uncompressed domain name labels. */ uint8_t rdata_parser_rrsig_get_labels(const uint8_t * NONNULL rdata); /*! * @brief * Get the original TTL of the records that are signed to generate the current RRSIG record. * * @param rdata * The pointer to the rdata of the RRSIG record. * * @result * The original TTL of the records that are signed. */ uint32_t rdata_parser_rrsig_get_original_ttl(const uint8_t * NONNULL rdata); /*! * @brief * Get the expiration date of the RRSIG record. * * @param rdata * The pointer to the rdata of the RRSIG record. * * @result * The expiration date of the RRSIG in epoch time. */ uint32_t rdata_parser_rrsig_get_signature_expiration(const uint8_t * NONNULL rdata); /*! * @brief * Get the inception date of the RRSIG record. * * @param rdata * The pointer to the rdata of the RRSIG record. * * @result * The inception date of the RRSIG in epoch time. */ uint32_t rdata_parser_rrsig_get_signature_inception(const uint8_t * NONNULL rdata); /*! * @brief * Get the key tag of the DNSKEY used to generate the current RRSIG record. * * @param rdata * The pointer to the rdata of the RRSIG record. * * @result * The key tag of the DNSKEY. */ uint16_t rdata_parser_rrsig_get_key_tag(const uint8_t * NONNULL rdata); /*! * @brief * Get the signer name of the RRSIG record. * * @param rdata * The pointer to the rdata of the RRSIG record. * * @result * The signer name of the RRSIG in domain name labels format. */ const uint8_t * NONNULL rdata_parser_rrsig_get_signer_name(const uint8_t * NONNULL rdata); /*! * @brief * Get the signature contained in the RRSIG record. * * @param rdata * The pointer to the rdata of the RRSIG record. * * @param rdata_len * The length of the rdata. * * @param out_signature_len * The pointer to the signature length value being returned for the returned signature pointer. * * @result * The signature data with the signature length returned in *out_signature_len. */ const uint8_t * NONNULL rdata_parser_rrsig_get_signature(const uint8_t * NONNULL rdata, uint16_t rdata_len, uint16_t * NONNULL out_signature_len); /*! * @brief * Check if the rdata format of the RRSIG is valid or not by checking the minimal length of the RRSIG members. * * @param rdata * The pointer to the rdata of the RRSIG record. * * @param rdata_len * The length of the rdata. * * @result * True if the rdata passes the check, otherwise, false. */ bool rdata_parser_rrsig_check_validity(const uint8_t * NONNULL rdata, uint16_t rdata_len); //====================================================================================================================== // MARK: - DNSKEY Parser /*! * @brief * Get the flags value from the DNSKEY rdata. * * @param rdata * The pointer to the rdata of the DNSKEY record. * * @result * The flags of DNSKEY record. */ uint16_t rdata_parser_dnskey_get_flags(const uint8_t * NONNULL rdata); /*! * @brief * Get the protocol of the DNSKEY. * * @param rdata * The pointer to the rdata of the DNSKEY record. * * @result * The protocol of the DNSKEY record. */ uint8_t rdata_parser_dnskey_get_protocol(const uint8_t * NONNULL rdata); /*! * @brief * Get the algorithm used by the DNSKEY record. * * @param rdata * The pointer to the rdata of the DNSKEY record. * * @result * The algorithm of the DNSKEY record. */ uint8_t rdata_parser_dnskey_get_algorithm(const uint8_t * NONNULL rdata); /*! * @brief * Get the public key bytes of the DNSKEY record. * * @param rdata * The pointer to the rdata of the DNSKEY record. * * @result * The public key in bytes. */ const uint8_t * NONNULL rdata_parser_dnskey_get_public_key(const uint8_t * NONNULL rdata); /*! * @brief * Get the size of the public key for the DNSKEY record. * * @param rdata_len * The length of the entire DNSKEY rdata in bytes. * * @result * The size of the public key bytes part of the DNSKEY rdata. */ uint16_t rdata_parser_dnskey_get_public_key_size(uint16_t rdata_len); /*! * @brief * Check if the rdata with the length is a valid rdata for DNSKEY record. * * @param rdata * The pointer to the DNSKEY rdata bytes. * * @param rdata_len * The length of the DNSKEY rdata, in bytes. * * @result * True if the rdata is a valid DNSKEY rdata format, otherwise, false. */ bool rdata_parser_dnskey_check_validity(const uint8_t * NONNULL rdata, uint16_t rdata_len); //====================================================================================================================== // MARK: - NSEC3 Parser /*! * @brief * Get the hash algorithm used to generate the next hashed owner name of the NSEC3 record. * * @param rdata * The pointer to the rdata of the NSEC3 record. * * @result * The hash algorithm. */ uint8_t rdata_parser_nsec3_get_hash_algorithm(const uint8_t * NONNULL rdata); /*! * @brief * Get the flags of the NSEC3 record. * * @param rdata * The pointer to the rdata of the NSEC3 record. * * @result * The flags. */ uint8_t rdata_parser_nsec3_get_flags(const uint8_t * NONNULL rdata); /*! * @brief * Get the extra number of hash iteration applied to generate the next hashed owner name of the NSEC3 record. * * @param rdata * The pointer to the rdata of the NSEC3 record. * * @result * The extra number of hash iteration. */ uint16_t rdata_parser_nsec3_get_iterations(const uint8_t * NONNULL rdata); /*! * @brief * Get the length of the salt added to the hash value when generating the next hashed owner name of the NSEC3 record. * * @param rdata * The pointer to the rdata of the NSEC3 record. * * @result * The length of the salt. */ uint8_t rdata_parser_nsec3_get_salt_length(const uint8_t * NONNULL rdata); /*! * @brief * Get the salt added to the hash value when generating the next hashed owner name of the NSEC3 record. * * @param rdata * The pointer to the rdata of the NSEC3 record. * * @result * The salt. */ const uint8_t * NONNULL rdata_parser_nsec3_get_salt(const uint8_t * NONNULL rdata); /*! * @brief * Get the bytes length of the next hashed owner name of the NSEC3 record. * * @param rdata * The pointer to the rdata of the NSEC3 record. * * @result * The length of the next hashed owner name that is in binary format. */ uint8_t rdata_parser_nsec3_get_hash_length(const uint8_t * NONNULL rdata); /*! * @brief * Get the next hashed owner name of the NSEC3 record, in binary format. * * @param rdata * The pointer to the rdata of the NSEC3 record. * * @result * The next hashed owner name that is in binary format. */ const uint8_t * NONNULL rdata_parser_nsec3_get_next_hashed_owner_name(const uint8_t * NONNULL rdata); /*! * @brief * Get the type bit maps of the NSEC3 record. * * @param rdata * The pointer to the rdata of the NSEC3 record. * * @param out_type_bit_maps_len * The pointer to the type bit maps length value being returned for the returned type bit maps. * * @result * The type bit maps that shows what types of DNS record is covered by the current NSEC3. */ const uint8_t * NONNULL rdata_parser_nsec3_get_type_bit_maps(const uint8_t * NONNULL rdata, uint16_t rdata_len, uint16_t * NONNULL out_type_bit_maps_len); /*! * @brief * Check if the rdata format of the NSEC3 is valid or not, by checking the minimal length of the NSEC3 members. * * @param rdata * The pointer to the rdata of the NSEC3 record. * * @param rdata_len * The length of the rdata. * * @result * True if the rdata passes the check, otherwise, false. */ bool rdata_parser_nsec3_check_validity(const uint8_t * NONNULL rdata, uint16_t rdata_len); #endif // RDATA_PARSER_H