1ae8c6e27Sflorian /* 2ae8c6e27Sflorian * validator/val_sigcrypt.h - validator signature crypto functions. 3ae8c6e27Sflorian * 4ae8c6e27Sflorian * Copyright (c) 2007, NLnet Labs. All rights reserved. 5ae8c6e27Sflorian * 6ae8c6e27Sflorian * This software is open source. 7ae8c6e27Sflorian * 8ae8c6e27Sflorian * Redistribution and use in source and binary forms, with or without 9ae8c6e27Sflorian * modification, are permitted provided that the following conditions 10ae8c6e27Sflorian * are met: 11ae8c6e27Sflorian * 12ae8c6e27Sflorian * Redistributions of source code must retain the above copyright notice, 13ae8c6e27Sflorian * this list of conditions and the following disclaimer. 14ae8c6e27Sflorian * 15ae8c6e27Sflorian * Redistributions in binary form must reproduce the above copyright notice, 16ae8c6e27Sflorian * this list of conditions and the following disclaimer in the documentation 17ae8c6e27Sflorian * and/or other materials provided with the distribution. 18ae8c6e27Sflorian * 19ae8c6e27Sflorian * Neither the name of the NLNET LABS nor the names of its contributors may 20ae8c6e27Sflorian * be used to endorse or promote products derived from this software without 21ae8c6e27Sflorian * specific prior written permission. 22ae8c6e27Sflorian * 23ae8c6e27Sflorian * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24ae8c6e27Sflorian * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25ae8c6e27Sflorian * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26ae8c6e27Sflorian * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27ae8c6e27Sflorian * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28ae8c6e27Sflorian * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 29ae8c6e27Sflorian * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30ae8c6e27Sflorian * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31ae8c6e27Sflorian * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32ae8c6e27Sflorian * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33ae8c6e27Sflorian * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34ae8c6e27Sflorian */ 35ae8c6e27Sflorian 36ae8c6e27Sflorian /** 37ae8c6e27Sflorian * \file 38ae8c6e27Sflorian * 39ae8c6e27Sflorian * This file contains helper functions for the validator module. 40ae8c6e27Sflorian * The functions help with signature verification and checking, the 41ae8c6e27Sflorian * bridging between RR wireformat data and crypto calls. 42ae8c6e27Sflorian */ 43ae8c6e27Sflorian 44ae8c6e27Sflorian #ifndef VALIDATOR_VAL_SIGCRYPT_H 45ae8c6e27Sflorian #define VALIDATOR_VAL_SIGCRYPT_H 46ae8c6e27Sflorian #include "util/data/packed_rrset.h" 47ae8c6e27Sflorian #include "sldns/pkthdr.h" 487a05b9dfSflorian #include "sldns/rrdef.h" 49ae8c6e27Sflorian struct val_env; 50ae8c6e27Sflorian struct module_env; 51ae8c6e27Sflorian struct module_qstate; 52ae8c6e27Sflorian struct ub_packed_rrset_key; 53ae8c6e27Sflorian struct rbtree_type; 54ae8c6e27Sflorian struct regional; 55ae8c6e27Sflorian struct sldns_buffer; 56ae8c6e27Sflorian 57ae8c6e27Sflorian /** number of entries in algorithm needs array */ 58ae8c6e27Sflorian #define ALGO_NEEDS_MAX 256 59ae8c6e27Sflorian 60ae8c6e27Sflorian /** 61ae8c6e27Sflorian * Storage for algorithm needs. DNSKEY algorithms. 62ae8c6e27Sflorian */ 63ae8c6e27Sflorian struct algo_needs { 64ae8c6e27Sflorian /** the algorithms (8-bit) with each a number. 65ae8c6e27Sflorian * 0: not marked. 66ae8c6e27Sflorian * 1: marked 'necessary but not yet fulfilled' 67ae8c6e27Sflorian * 2: marked bogus. 68ae8c6e27Sflorian * Indexed by algorithm number. 69ae8c6e27Sflorian */ 70ae8c6e27Sflorian uint8_t needs[ALGO_NEEDS_MAX]; 71ae8c6e27Sflorian /** the number of entries in the array that are unfulfilled */ 72ae8c6e27Sflorian size_t num; 73ae8c6e27Sflorian }; 74ae8c6e27Sflorian 75ae8c6e27Sflorian /** 76ae8c6e27Sflorian * Initialize algo needs structure, set algos from rrset as needed. 77ae8c6e27Sflorian * Results are added to an existing need structure. 78ae8c6e27Sflorian * @param n: struct with storage. 79ae8c6e27Sflorian * @param dnskey: algos from this struct set as necessary. DNSKEY set. 80ae8c6e27Sflorian * @param sigalg: adds to signalled algorithm list too. 81ae8c6e27Sflorian */ 82ae8c6e27Sflorian void algo_needs_init_dnskey_add(struct algo_needs* n, 83ae8c6e27Sflorian struct ub_packed_rrset_key* dnskey, uint8_t* sigalg); 84ae8c6e27Sflorian 85ae8c6e27Sflorian /** 86ae8c6e27Sflorian * Initialize algo needs structure from a signalled algo list. 87ae8c6e27Sflorian * @param n: struct with storage. 88ae8c6e27Sflorian * @param sigalg: signalled algorithm list, numbers ends with 0. 89ae8c6e27Sflorian */ 90ae8c6e27Sflorian void algo_needs_init_list(struct algo_needs* n, uint8_t* sigalg); 91ae8c6e27Sflorian 92ae8c6e27Sflorian /** 93ae8c6e27Sflorian * Initialize algo needs structure, set algos from rrset as needed. 94ae8c6e27Sflorian * @param n: struct with storage. 95ae8c6e27Sflorian * @param ds: algos from this struct set as necessary. DS set. 96ae8c6e27Sflorian * @param fav_ds_algo: filter to use only this DS algo. 97ae8c6e27Sflorian * @param sigalg: list of signalled algos, constructed as output, 98ae8c6e27Sflorian * provide size ALGO_NEEDS_MAX+1. list of algonumbers, ends with a zero. 99ae8c6e27Sflorian */ 100ae8c6e27Sflorian void algo_needs_init_ds(struct algo_needs* n, struct ub_packed_rrset_key* ds, 101ae8c6e27Sflorian int fav_ds_algo, uint8_t* sigalg); 102ae8c6e27Sflorian 103ae8c6e27Sflorian /** 104ae8c6e27Sflorian * Mark this algorithm as a success, sec_secure, and see if we are done. 105ae8c6e27Sflorian * @param n: storage structure processed. 106ae8c6e27Sflorian * @param algo: the algorithm processed to be secure. 107ae8c6e27Sflorian * @return if true, processing has finished successfully, we are satisfied. 108ae8c6e27Sflorian */ 109ae8c6e27Sflorian int algo_needs_set_secure(struct algo_needs* n, uint8_t algo); 110ae8c6e27Sflorian 111ae8c6e27Sflorian /** 112ae8c6e27Sflorian * Mark this algorithm a failure, sec_bogus. It can later be overridden 113ae8c6e27Sflorian * by a success for this algorithm (with a different signature). 114ae8c6e27Sflorian * @param n: storage structure processed. 115ae8c6e27Sflorian * @param algo: the algorithm processed to be bogus. 116ae8c6e27Sflorian */ 117ae8c6e27Sflorian void algo_needs_set_bogus(struct algo_needs* n, uint8_t algo); 118ae8c6e27Sflorian 119ae8c6e27Sflorian /** 120ae8c6e27Sflorian * See how many algorithms are missing (not bogus or secure, but not processed) 121ae8c6e27Sflorian * @param n: storage structure processed. 122ae8c6e27Sflorian * @return number of algorithms missing after processing. 123ae8c6e27Sflorian */ 124ae8c6e27Sflorian size_t algo_needs_num_missing(struct algo_needs* n); 125ae8c6e27Sflorian 126ae8c6e27Sflorian /** 127ae8c6e27Sflorian * See which algo is missing. 128ae8c6e27Sflorian * @param n: struct after processing. 129ae8c6e27Sflorian * @return if 0 an algorithm was bogus, if a number, this algorithm was 130ae8c6e27Sflorian * missing. So on 0, report why that was bogus, on number report a missing 131ae8c6e27Sflorian * algorithm. There could be multiple missing, this reports the first one. 132ae8c6e27Sflorian */ 133ae8c6e27Sflorian int algo_needs_missing(struct algo_needs* n); 134ae8c6e27Sflorian 135ae8c6e27Sflorian /** 136ae8c6e27Sflorian * Format error reason for algorithm missing. 137ae8c6e27Sflorian * @param alg: DNSKEY-algorithm missing. 138ae8c6e27Sflorian * @param reason: destination. 139ae8c6e27Sflorian * @param s: string, appended with 'with algorithm ..'. 140*7037e34cSflorian * @param reasonbuf: buffer to use for fail reason string print. 141*7037e34cSflorian * @param reasonlen: length of reasonbuf. 142ae8c6e27Sflorian */ 143*7037e34cSflorian void algo_needs_reason(int alg, char** reason, char* s, char* reasonbuf, 144*7037e34cSflorian size_t reasonlen); 145ae8c6e27Sflorian 146ae8c6e27Sflorian /** 147ae8c6e27Sflorian * Check if dnskey matches a DS digest 148ae8c6e27Sflorian * Does not check dnskey-keyid footprint, just the digest. 149ae8c6e27Sflorian * @param env: module environment. Uses scratch space. 150ae8c6e27Sflorian * @param dnskey_rrset: DNSKEY rrset. 151ae8c6e27Sflorian * @param dnskey_idx: index of RR in rrset. 152ae8c6e27Sflorian * @param ds_rrset: DS rrset 153ae8c6e27Sflorian * @param ds_idx: index of RR in DS rrset. 154ae8c6e27Sflorian * @return true if it matches, false on error, not supported or no match. 155ae8c6e27Sflorian */ 156ae8c6e27Sflorian int ds_digest_match_dnskey(struct module_env* env, 157ae8c6e27Sflorian struct ub_packed_rrset_key* dnskey_rrset, size_t dnskey_idx, 158ae8c6e27Sflorian struct ub_packed_rrset_key* ds_rrset, size_t ds_idx); 159ae8c6e27Sflorian 160ae8c6e27Sflorian /** 161ae8c6e27Sflorian * Get dnskey keytag, footprint value 162ae8c6e27Sflorian * @param dnskey_rrset: DNSKEY rrset. 163ae8c6e27Sflorian * @param dnskey_idx: index of RR in rrset. 164ae8c6e27Sflorian * @return the keytag or 0 for badly formatted DNSKEYs. 165ae8c6e27Sflorian */ 166ae8c6e27Sflorian uint16_t dnskey_calc_keytag(struct ub_packed_rrset_key* dnskey_rrset, 167ae8c6e27Sflorian size_t dnskey_idx); 168ae8c6e27Sflorian 169ae8c6e27Sflorian /** 170ae8c6e27Sflorian * Get DS keytag, footprint value that matches the DNSKEY keytag it signs. 171ae8c6e27Sflorian * @param ds_rrset: DS rrset 172ae8c6e27Sflorian * @param ds_idx: index of RR in DS rrset. 173ae8c6e27Sflorian * @return the keytag or 0 for badly formatted DSs. 174ae8c6e27Sflorian */ 175ae8c6e27Sflorian uint16_t ds_get_keytag(struct ub_packed_rrset_key* ds_rrset, size_t ds_idx); 176ae8c6e27Sflorian 177ae8c6e27Sflorian /** 178ae8c6e27Sflorian * See if DNSKEY algorithm is supported 179ae8c6e27Sflorian * @param dnskey_rrset: DNSKEY rrset. 180ae8c6e27Sflorian * @param dnskey_idx: index of RR in rrset. 181ae8c6e27Sflorian * @return true if supported. 182ae8c6e27Sflorian */ 183ae8c6e27Sflorian int dnskey_algo_is_supported(struct ub_packed_rrset_key* dnskey_rrset, 184ae8c6e27Sflorian size_t dnskey_idx); 185ae8c6e27Sflorian 186ae8c6e27Sflorian /** 187411c5950Sflorian * See if the DNSKEY size at that algorithm is supported. 188411c5950Sflorian * @param dnskey_rrset: DNSKEY rrset. 189411c5950Sflorian * @param dnskey_idx: index of RR in rrset. 190411c5950Sflorian * @return true if supported. 191411c5950Sflorian */ 192411c5950Sflorian int dnskey_size_is_supported(struct ub_packed_rrset_key* dnskey_rrset, 193411c5950Sflorian size_t dnskey_idx); 194411c5950Sflorian 195411c5950Sflorian /** 196411c5950Sflorian * See if the DNSKEY size at that algorithm is supported for all the 197411c5950Sflorian * RRs in the DNSKEY RRset. 198411c5950Sflorian * @param dnskey_rrset: DNSKEY rrset. 199411c5950Sflorian * @return true if supported. 200411c5950Sflorian */ 201411c5950Sflorian int dnskeyset_size_is_supported(struct ub_packed_rrset_key* dnskey_rrset); 202411c5950Sflorian 203411c5950Sflorian /** 204ae8c6e27Sflorian * See if DS digest algorithm is supported 205ae8c6e27Sflorian * @param ds_rrset: DS rrset 206ae8c6e27Sflorian * @param ds_idx: index of RR in DS rrset. 207ae8c6e27Sflorian * @return true if supported. 208ae8c6e27Sflorian */ 209ae8c6e27Sflorian int ds_digest_algo_is_supported(struct ub_packed_rrset_key* ds_rrset, 210ae8c6e27Sflorian size_t ds_idx); 211ae8c6e27Sflorian 212ae8c6e27Sflorian /** 213ae8c6e27Sflorian * Get DS RR digest algorithm 214ae8c6e27Sflorian * @param ds_rrset: DS rrset. 215ae8c6e27Sflorian * @param ds_idx: which DS. 216ae8c6e27Sflorian * @return algorithm or 0 if DS too short. 217ae8c6e27Sflorian */ 218ae8c6e27Sflorian int ds_get_digest_algo(struct ub_packed_rrset_key* ds_rrset, size_t ds_idx); 219ae8c6e27Sflorian 220ae8c6e27Sflorian /** 221ae8c6e27Sflorian * See if DS key algorithm is supported 222ae8c6e27Sflorian * @param ds_rrset: DS rrset 223ae8c6e27Sflorian * @param ds_idx: index of RR in DS rrset. 224ae8c6e27Sflorian * @return true if supported. 225ae8c6e27Sflorian */ 226ae8c6e27Sflorian int ds_key_algo_is_supported(struct ub_packed_rrset_key* ds_rrset, 227ae8c6e27Sflorian size_t ds_idx); 228ae8c6e27Sflorian 229ae8c6e27Sflorian /** 230ae8c6e27Sflorian * Get DS RR key algorithm. This value should match with the DNSKEY algo. 231ae8c6e27Sflorian * @param k: DS rrset. 232ae8c6e27Sflorian * @param idx: which DS. 233ae8c6e27Sflorian * @return algorithm or 0 if DS too short. 234ae8c6e27Sflorian */ 235ae8c6e27Sflorian int ds_get_key_algo(struct ub_packed_rrset_key* k, size_t idx); 236ae8c6e27Sflorian 237ae8c6e27Sflorian /** 238ae8c6e27Sflorian * Get DNSKEY RR signature algorithm 239ae8c6e27Sflorian * @param k: DNSKEY rrset. 240ae8c6e27Sflorian * @param idx: which DNSKEY RR. 241ae8c6e27Sflorian * @return algorithm or 0 if DNSKEY too short. 242ae8c6e27Sflorian */ 243ae8c6e27Sflorian int dnskey_get_algo(struct ub_packed_rrset_key* k, size_t idx); 244ae8c6e27Sflorian 245ae8c6e27Sflorian /** 246ae8c6e27Sflorian * Get DNSKEY RR flags 247ae8c6e27Sflorian * @param k: DNSKEY rrset. 248ae8c6e27Sflorian * @param idx: which DNSKEY RR. 249ae8c6e27Sflorian * @return flags or 0 if DNSKEY too short. 250ae8c6e27Sflorian */ 251ae8c6e27Sflorian uint16_t dnskey_get_flags(struct ub_packed_rrset_key* k, size_t idx); 252ae8c6e27Sflorian 253ae8c6e27Sflorian /** 254ae8c6e27Sflorian * Verify rrset against dnskey rrset. 255ae8c6e27Sflorian * @param env: module environment, scratch space is used. 256ae8c6e27Sflorian * @param ve: validator environment, date settings. 257ae8c6e27Sflorian * @param rrset: to be validated. 258ae8c6e27Sflorian * @param dnskey: DNSKEY rrset, keyset to try. 259ae8c6e27Sflorian * @param sigalg: if nonNULL provide downgrade protection otherwise one 260ae8c6e27Sflorian * algorithm is enough. 261ae8c6e27Sflorian * @param reason: if bogus, a string returned, fixed or alloced in scratch. 2627a05b9dfSflorian * @param reason_bogus: EDE (RFC8914) code paired with the reason of failure. 263ae8c6e27Sflorian * @param section: section of packet where this rrset comes from. 264ae8c6e27Sflorian * @param qstate: qstate with region. 265fed3efa7Sflorian * @param verified: if not NULL the number of RRSIG validations is returned. 266*7037e34cSflorian * @param reasonbuf: buffer to use for fail reason string print. 267*7037e34cSflorian * @param reasonlen: length of reasonbuf. 268ae8c6e27Sflorian * @return SECURE if one key in the set verifies one rrsig. 269ae8c6e27Sflorian * UNCHECKED on allocation errors, unsupported algorithms, malformed data, 270ae8c6e27Sflorian * and BOGUS on verification failures (no keys match any signatures). 271ae8c6e27Sflorian */ 272ae8c6e27Sflorian enum sec_status dnskeyset_verify_rrset(struct module_env* env, 273ae8c6e27Sflorian struct val_env* ve, struct ub_packed_rrset_key* rrset, 2747a05b9dfSflorian struct ub_packed_rrset_key* dnskey, uint8_t* sigalg, 2757a05b9dfSflorian char** reason, sldns_ede_code *reason_bogus, 276*7037e34cSflorian sldns_pkt_section section, struct module_qstate* qstate, int* verified, 277*7037e34cSflorian char* reasonbuf, size_t reasonlen); 2787a05b9dfSflorian 279ae8c6e27Sflorian /** 280ae8c6e27Sflorian * verify rrset against one specific dnskey (from rrset) 281ae8c6e27Sflorian * @param env: module environment, scratch space is used. 282ae8c6e27Sflorian * @param ve: validator environment, date settings. 283ae8c6e27Sflorian * @param rrset: to be validated. 284ae8c6e27Sflorian * @param dnskey: DNSKEY rrset, keyset. 285ae8c6e27Sflorian * @param dnskey_idx: which key from the rrset to try. 286ae8c6e27Sflorian * @param reason: if bogus, a string returned, fixed or alloced in scratch. 2877a05b9dfSflorian * @param reason_bogus: EDE (RFC8914) code paired with the reason of failure. 288ae8c6e27Sflorian * @param section: section of packet where this rrset comes from. 289ae8c6e27Sflorian * @param qstate: qstate with region. 290ae8c6e27Sflorian * @return secure if *this* key signs any of the signatures on rrset. 291ae8c6e27Sflorian * unchecked on error or and bogus on bad signature. 292ae8c6e27Sflorian */ 2937a05b9dfSflorian enum sec_status dnskey_verify_rrset(struct module_env* env, struct val_env* ve, 2947a05b9dfSflorian struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey, 2957a05b9dfSflorian size_t dnskey_idx, char** reason, sldns_ede_code *reason_bogus, 296ae8c6e27Sflorian sldns_pkt_section section, struct module_qstate* qstate); 297ae8c6e27Sflorian 298ae8c6e27Sflorian /** 299ae8c6e27Sflorian * verify rrset, with specific dnskey(from set), for a specific rrsig 300ae8c6e27Sflorian * @param region: scratch region used for temporary allocation. 301ae8c6e27Sflorian * @param buf: scratch buffer used for canonicalized rrset data. 302ae8c6e27Sflorian * @param ve: validator environment, date settings. 303ae8c6e27Sflorian * @param now: current time for validation (can be overridden). 304ae8c6e27Sflorian * @param rrset: to be validated. 305ae8c6e27Sflorian * @param dnskey: DNSKEY rrset, keyset. 306ae8c6e27Sflorian * @param dnskey_idx: which key from the rrset to try. 307ae8c6e27Sflorian * @param sig_idx: which signature to try to validate. 308ae8c6e27Sflorian * @param sortree: pass NULL at start, the sorted rrset order is returned. 309ae8c6e27Sflorian * pass it again for the same rrset. 310ae8c6e27Sflorian * @param buf_canon: if true, the buffer is already canonical. 311ae8c6e27Sflorian * pass false at start. pass old value only for same rrset and same 312ae8c6e27Sflorian * signature (but perhaps different key) for reuse. 313ae8c6e27Sflorian * @param reason: if bogus, a string returned, fixed or alloced in scratch. 3147a05b9dfSflorian * @param reason_bogus: EDE (8914) code paired with the reason of failure. 315ae8c6e27Sflorian * @param section: section of packet where this rrset comes from. 316ae8c6e27Sflorian * @param qstate: qstate with region. 317ae8c6e27Sflorian * @return secure if this key signs this signature. unchecked on error or 318ae8c6e27Sflorian * bogus if it did not validate. 319ae8c6e27Sflorian */ 320ae8c6e27Sflorian enum sec_status dnskey_verify_rrset_sig(struct regional* region, 321ae8c6e27Sflorian struct sldns_buffer* buf, struct val_env* ve, time_t now, 322ae8c6e27Sflorian struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey, 323ae8c6e27Sflorian size_t dnskey_idx, size_t sig_idx, 3247a05b9dfSflorian struct rbtree_type** sortree, int* buf_canon, 3257a05b9dfSflorian char** reason, sldns_ede_code *reason_bogus, 326ae8c6e27Sflorian sldns_pkt_section section, struct module_qstate* qstate); 327ae8c6e27Sflorian 328ae8c6e27Sflorian /** 329ae8c6e27Sflorian * canonical compare for two tree entries 330ae8c6e27Sflorian */ 331ae8c6e27Sflorian int canonical_tree_compare(const void* k1, const void* k2); 332ae8c6e27Sflorian 333ae8c6e27Sflorian /** 334ae8c6e27Sflorian * Compare two rrsets and see if they are the same, canonicalised. 335ae8c6e27Sflorian * The rrsets are not altered. 336ae8c6e27Sflorian * @param region: temporary region. 337ae8c6e27Sflorian * @param k1: rrset1 338ae8c6e27Sflorian * @param k2: rrset2 339ae8c6e27Sflorian * @return true if equal. 340ae8c6e27Sflorian */ 341ae8c6e27Sflorian int rrset_canonical_equal(struct regional* region, 342ae8c6e27Sflorian struct ub_packed_rrset_key* k1, struct ub_packed_rrset_key* k2); 343ae8c6e27Sflorian 344411c5950Sflorian /** 345411c5950Sflorian * Canonicalize an rrset into the buffer. For an auth zone record, so 346411c5950Sflorian * this does not use a signature, or the RRSIG TTL or the wildcard label 347411c5950Sflorian * count from the RRSIG. 348411c5950Sflorian * @param region: temporary region. 349411c5950Sflorian * @param buf: the buffer to use. 350411c5950Sflorian * @param k: the rrset to insert. 351411c5950Sflorian * @return false on alloc error. 352411c5950Sflorian */ 353411c5950Sflorian int rrset_canonicalize_to_buffer(struct regional* region, 354411c5950Sflorian struct sldns_buffer* buf, struct ub_packed_rrset_key* k); 355411c5950Sflorian 356ae8c6e27Sflorian #endif /* VALIDATOR_VAL_SIGCRYPT_H */ 357