dnssec.h 5.33 KB
Newer Older
1
/*  Copyright (C) 2015-2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
2 3 4 5 6 7 8 9 10 11 12 13

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
14
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
15 16 17 18
 */

#pragma once

19
#include "lib/defines.h"
20
#include "lib/utils.h"
21 22
#include <libknot/packet/pkt.h>

23 24 25
/**
 * Initialise cryptographic back-end.
 */
26
KR_EXPORT
27 28 29 30 31
void kr_crypto_init(void);

/**
 * De-initialise cryptographic back-end.
 */
32
KR_EXPORT
33 34 35 36 37 38
void kr_crypto_cleanup(void);

/**
 * Re-initialise cryptographic back-end.
 * @note Must be called after fork() in the child.
 */
39
KR_EXPORT
40
void kr_crypto_reinit(void);
41

42 43 44
/** Opaque DNSSEC key pointer. */
struct dseckey;

45
#define KR_DNSSEC_VFLG_WEXPAND 0x01
46
#define KR_DNSSEC_VFLG_OPTOUT  0x02
47 48 49 50

/** DNSSEC validation context. */
struct kr_rrset_validation_ctx {
	const knot_pkt_t *pkt;		/*!< Packet to be validated. */
51
	ranked_rr_array_t *rrs;		/*!< List of preselected RRs to be validated. */
52 53 54 55 56
	knot_section_t section_id;	/*!< Section to work with. */
	const knot_rrset_t *keys;	/*!< DNSKEY RRSet. */
        const knot_dname_t *zone_name;	/*!< Name of the zone containing the RRSIG RRSet. */
	uint32_t timestamp;		/*!< Validation time. */
        bool has_nsec3;			/*!< Whether to use NSEC3 validation. */
57
	uint32_t qry_uid;		/*!< Current query uid. */
58
	uint32_t flags;			/*!< Output - Flags. */
59
	uint32_t err_cnt;		/*!< Output - Number of validation failures. */
60
	int result;			/*!< Output - 0 or error code. */
61 62 63 64 65 66 67 68 69 70
	struct {
		unsigned int matching_name_type;	/*!< Name + type matches */
		unsigned int expired;
		unsigned int notyet;
		unsigned int signer_invalid;		/*!< Signer is not zone apex */
		unsigned int labels_invalid;		/*!< Number of labels in RRSIG */
		unsigned int key_invalid;		/*!< Algorithm/keytag/key owner */
		unsigned int crypto_invalid;
		unsigned int nsec_invalid;
	} rrs_counters;	/*!< Error counters for single RRset validation. */
71 72 73 74
};

typedef struct kr_rrset_validation_ctx kr_rrset_validation_ctx_t;

75 76
/**
 * Validate RRSet.
77 78 79
 * @param vctx    Pointer to validation context.
 * @param covered RRSet covered by a signature. It must be in canonical format.
 * @return        0 or error code, same as vctx->result.
80
 */
81 82
int kr_rrset_validate(kr_rrset_validation_ctx_t *vctx,
			const knot_rrset_t *covered);
83

84 85 86 87 88 89
/**
 * Return true iff the RRset contains at least one usable DS.  See RFC6840 5.2.
 */
KR_EXPORT KR_PURE
bool kr_ds_algo_support(const knot_rrset_t *ta);

90 91
/**
 * Check whether the DNSKEY rrset matches the supplied trust anchor RRSet.
92 93
 * @param vctx  Pointer to validation context.
 * @param ta    Trust anchor RRSet against which to validate the DNSKEY RRSet.
94
 * @return      0 or error code, same as vctx->result.
95
 */
96
int kr_dnskeys_trusted(kr_rrset_validation_ctx_t *vctx, const knot_rrset_t *ta);
97

98
/** Return true if the DNSKEY can be used as a ZSK.  */
99
KR_EXPORT KR_PURE
100 101
bool kr_dnssec_key_zsk(const uint8_t *dnskey_rdata);

102
/** Return true if the DNSKEY indicates being KSK (=> has SEP).  */
103
KR_EXPORT KR_PURE
104 105 106
bool kr_dnssec_key_ksk(const uint8_t *dnskey_rdata);

/** Return true if the DNSKEY is revoked. */
107
KR_EXPORT KR_PURE
108 109
bool kr_dnssec_key_revoked(const uint8_t *dnskey_rdata);

110 111 112 113 114 115
/** Return DNSKEY tag.
  * @param rrtype RR type (either DS or DNSKEY are supported)
  * @param rdata  Key/digest RDATA.
  * @param rdlen  RDATA length.
  * @return Key tag (positive number), or an error code
  */
116
KR_EXPORT KR_PURE
117
int kr_dnssec_key_tag(uint16_t rrtype, const uint8_t *rdata, size_t rdlen);
118 119 120 121 122 123 124 125 126

/** Return 0 if the two keys are identical.
  * @note This compares RDATA only, algorithm and public key must match.
  * @param key_a_rdata First key RDATA
  * @param key_a_rdlen First key RDATA length
  * @param key_b_rdata Second key RDATA
  * @param key_b_rdlen Second key RDATA length
  * @return 0 if they match or an error code
  */
127
KR_EXPORT KR_PURE
128 129 130
int kr_dnssec_key_match(const uint8_t *key_a_rdata, size_t key_a_rdlen,
                        const uint8_t *key_b_rdata, size_t key_b_rdlen);

131 132
/**
 * Construct a DNSSEC key.
133 134 135 136
 * @param key   Pointer to be set to newly created DNSSEC key.
 * @param kown  DNSKEY owner name.
 * @param rdata DNSKEY RDATA
 * @param rdlen DNSKEY RDATA length
137
 * @return 0 or error code; in particular: DNSSEC_INVALID_KEY_ALGORITHM
138
 */
139
int kr_dnssec_key_from_rdata(struct dseckey **key, const knot_dname_t *kown, const uint8_t *rdata, size_t rdlen);
140 141 142 143 144 145

/**
 * Frees the DNSSEC key.
 * @param key Pointer to freed key.
 */
void kr_dnssec_key_free(struct dseckey **key);
146 147

/**
148 149 150 151 152 153
 * Checks whether NSEC/NSEC3 RR selected by iterator matches the supplied name and type.
 * @param rrs     Records selected by iterator.
 * @param qry_uid Query unique identifier where NSEC/NSEC3 belongs to.
 * @param name    Name to be checked.
 * @param type    Type to be checked.
 * @return        0 or error code.
154 155 156
 */
int kr_dnssec_matches_name_and_type(const ranked_rr_array_t *rrs, uint32_t qry_uid,
				    const knot_dname_t *name, uint16_t type);