17 #include <openssl/hmac.h>
18 #include <openssl/md5.h>
55 ldns_tsig_prepare_pkt_wire(
const uint8_t *wire,
size_t wire_len,
size_t *result_len)
57 uint8_t *wire2 = NULL;
86 for (i = 0; i < qd_count; i++) {
94 for (i = 0; i < an_count; i++) {
102 for (i = 0; i < ns_count; i++) {
110 for (i = 0; i < ar_count; i++) {
124 memcpy(wire2, wire, *result_len);
132 static const EVP_MD *
133 ldns_digest_function(
char *name)
137 if (strcasecmp(name,
"hmac-sha512.") == 0) {
138 #ifdef HAVE_EVP_SHA512
143 }
else if (strcasecmp(name,
"hmac-shac384.") == 0) {
144 #ifdef HAVE_EVP_SHA384
149 }
else if (strcasecmp(name,
"hmac-sha256.") == 0) {
150 #ifdef HAVE_EVP_SHA256
155 }
else if (strcasecmp(name,
"hmac-sha1.") == 0) {
157 }
else if (strcasecmp(name,
"hmac-md5.sig-alg.reg.int.") == 0) {
167 ldns_tsig_mac_new(
ldns_rdf **tsig_mac,
const uint8_t *pkt_wire,
size_t pkt_wire_size,
168 const char *key_data,
const ldns_rdf *key_name_rdf,
const ldns_rdf *fudge_rdf,
170 const ldns_rdf *other_data_rdf,
const ldns_rdf *orig_mac_rdf,
int tsig_timers_only)
175 unsigned char *mac_bytes = NULL;
176 unsigned char *key_bytes = NULL;
178 const EVP_MD *digester;
179 char *algorithm_name = NULL;
180 unsigned int md_len = EVP_MAX_MD_SIZE;
183 ldns_rdf *canonical_key_name_rdf = NULL;
184 ldns_rdf *canonical_algorithm_rdf = NULL;
186 if (key_name_rdf == NULL || algorithm_rdf == NULL) {
190 if (canonical_key_name_rdf == NULL) {
194 if (canonical_algorithm_rdf == NULL) {
210 ldns_buffer_write(data_buffer, pkt_wire, pkt_wire_size);
211 if (!tsig_timers_only) {
214 canonical_key_name_rdf);
216 ldns_buffer_write_u32(data_buffer, 0);
219 canonical_algorithm_rdf);
223 if (!tsig_timers_only) {
228 wireformat = (
char *) data_buffer->
_data;
229 wiresize = (
int) ldns_buffer_position(data_buffer);
232 if(!algorithm_name) {
239 ldns_b64_pton_calculate_size(strlen(key_data)));
245 ldns_b64_pton_calculate_size(strlen(key_data)));
257 memset(mac_bytes, 0, md_len+2);
259 digester = ldns_digest_function(algorithm_name);
262 (void) HMAC(digester, key_bytes, key_size, (
void *)wireformat,
263 (size_t) wiresize, mac_bytes + 2, &md_len);
265 ldns_write_uint16(mac_bytes, md_len);
289 const char *key_data,
const ldns_rdf *orig_mac_rdf)
296 const char *key_data,
const ldns_rdf *orig_mac_rdf,
int tsig_timers_only)
307 uint16_t pkt_id, orig_pkt_id;
310 uint8_t *prepared_wire = NULL;
311 size_t prepared_wire_size = 0;
334 prepared_wire = ldns_tsig_prepare_pkt_wire(wire, wirelen, &prepared_wire_size);
336 status = ldns_tsig_mac_new(&my_mac_rdf, prepared_wire, prepared_wire_size,
337 key_data, key_name_rdf, fudge_rdf, algorithm_rdf,
338 time_signed_rdf, error_rdf, other_data_rdf, orig_mac_rdf, tsig_timers_only);
377 uint16_t fudge,
const char *algorithm_name,
const ldns_rdf *query_mac)
384 uint16_t fudge,
const char *algorithm_name,
const ldns_rdf *query_mac,
int tsig_timers_only)
397 uint8_t *pkt_wire = NULL;
400 struct timeval tv_time_signed;
401 uint8_t *time_signed = NULL;
405 if(!key_name_rdf || !algorithm_rdf) {
412 if (gettimeofday(&tv_time_signed, NULL) == 0) {
418 ldns_write_uint64_as_uint48(time_signed,
419 (uint64_t)tv_time_signed.tv_sec);
426 if(!time_signed_rdf) {
440 if(!fudge_rdf || !orig_id_rdf || !error_rdf || !other_data_rdf) {
450 status = ldns_tsig_mac_new(&mac_rdf, pkt_wire, pkt_wire_len,
451 key_data, key_name_rdf, fudge_rdf, algorithm_rdf,
452 time_signed_rdf, error_rdf, other_data_rdf, query_mac, tsig_timers_only);
void ldns_buffer_free(ldns_buffer *buffer)
frees the buffer.
ldns_buffer * ldns_buffer_new(size_t capacity)
creates a new buffer with the specified capacity.
#define HAVE_CRYPTO_MEMCMP
int ldns_b64_pton(char const *src, uint8_t *target, size_t targsize)
void ldns_dname2canonical(const ldns_rdf *rdf)
Put a dname into canonical fmt - ie.
@ LDNS_STATUS_INTERNAL_ERR
@ LDNS_STATUS_CRYPTO_UNKNOWN_ALGO
@ LDNS_STATUS_INVALID_B64
enum ldns_enum_status ldns_status
char * ldns_rdf2str(const ldns_rdf *rdf)
Converts the data in the rdata field to presentation format and returns that as a char *.
ldns_status ldns_pkt2wire(uint8_t **dest, const ldns_pkt *p, size_t *size)
Allocates an array of uint8_t at dest, and puts the wireformat of the given packet in that array.
ldns_status ldns_rdf2buffer_wire(ldns_buffer *output, const ldns_rdf *rdf)
Copies the rdata data to the buffer in wire format.
Including this file will include all ldns files, and define some lookup tables.
#define LDNS_MAX_PACKETLEN
ldns_rr * ldns_pkt_tsig(const ldns_pkt *p)
Return the packet's tsig pseudo rr's.
uint16_t ldns_pkt_id(const ldns_pkt *p)
Read the packet id.
void ldns_pkt_set_id(ldns_pkt *p, uint16_t id)
Set the packet's id.
void ldns_pkt_set_tsig(ldns_pkt *p, ldns_rr *t)
Set the packet's tsig rr.
@ LDNS_SECTION_ADDITIONAL
void ldns_rdf_deep_free(ldns_rdf *rd)
frees a rdf structure and frees the data.
ldns_rdf * ldns_rdf_new(ldns_rdf_type type, size_t size, void *data)
allocates a new rdf structure and fills it.
ldns_rdf * ldns_native2rdf_int16_data(size_t size, uint8_t *data)
returns an int16_data rdf that contains the data in the given array, preceded by an int16 specifying ...
uint16_t ldns_rdf2native_int16(const ldns_rdf *rd)
returns the native uint16_t representation from the rdf.
ldns_rdf * ldns_rdf_new_frm_str(ldns_rdf_type type, const char *str)
creates a new rdf from a string.
ldns_rdf * ldns_native2rdf_int16(ldns_rdf_type type, uint16_t value)
returns the rdf containing the native uint16_t representation.
@ LDNS_RDF_TYPE_DNAME
domain name
@ LDNS_RDF_TYPE_INT16_DATA
variable length any type rdata where the length is specified by the first 2 bytes
@ LDNS_RDF_TYPE_INT16
16 bits
@ LDNS_RDF_TYPE_TSIGTIME
tsig time 48 bits
size_t ldns_rdf_size(const ldns_rdf *rd)
returns the size of the rdf.
uint8_t * ldns_rdf_data(const ldns_rdf *rd)
returns the data of the rdf.
void ldns_rdf_free(ldns_rdf *rd)
frees a rdf structure, leaving the data pointer intact.
ldns_rdf * ldns_rdf_clone(const ldns_rdf *rd)
clones a rdf structure.
ldns_rdf * ldns_rdf_new_frm_data(ldns_rdf_type type, size_t size, const void *data)
allocates a new rdf structure and fills it.
void ldns_rr_free(ldns_rr *rr)
frees an RR structure
void ldns_rr_set_owner(ldns_rr *rr, ldns_rdf *owner)
sets the owner in the rr structure.
void ldns_rr_set_type(ldns_rr *rr, ldns_rr_type rr_type)
sets the type in the rr.
size_t ldns_rr_rd_count(const ldns_rr *rr)
returns the rd_count of an rr structure.
void ldns_rr_set_ttl(ldns_rr *rr, uint32_t ttl)
sets the ttl in the rr structure.
void ldns_rr_set_class(ldns_rr *rr, ldns_rr_class rr_class)
sets the class in the rr.
signed char ldns_rr_push_rdf(ldns_rr *rr, const ldns_rdf *f)
sets rd_field member, it will be placed in the next available spot.
@ LDNS_RR_CLASS_ANY
Any class.
ldns_rdf * ldns_rr_rdf(const ldns_rr *rr, size_t nr)
returns the rdata field member counter.
ldns_rr * ldns_rr_new(void)
creates a new rr structure.
implementation of buffers to ease operations
uint8_t * _data
The data contained in the buffer.
Resource record data field.
Contains credentials for TSIG.
const char * ldns_tsig_keyname(const ldns_tsig_credentials *tc)
ldns_status ldns_pkt_tsig_sign_next(ldns_pkt *pkt, const char *key_name, const char *key_data, uint16_t fudge, const char *algorithm_name, const ldns_rdf *query_mac, int tsig_timers_only)
creates a tsig rr for the given packet and key.
char * ldns_tsig_keyname_clone(const ldns_tsig_credentials *tc)
signed char ldns_pkt_tsig_verify_next(ldns_pkt *pkt, const uint8_t *wire, size_t wirelen, const char *key_name, const char *key_data, const ldns_rdf *orig_mac_rdf, int tsig_timers_only)
verifies the tsig rr for the given packet and key.
const char * ldns_tsig_keydata(const ldns_tsig_credentials *tc)
const char * ldns_tsig_algorithm(const ldns_tsig_credentials *tc)
signed char ldns_pkt_tsig_verify(ldns_pkt *pkt, const uint8_t *wire, size_t wirelen, const char *key_name, const char *key_data, const ldns_rdf *orig_mac_rdf)
verifies the tsig rr for the given packet and key.
ldns_status ldns_pkt_tsig_sign(ldns_pkt *pkt, const char *key_name, const char *key_data, uint16_t fudge, const char *algorithm_name, const ldns_rdf *query_mac)
creates a tsig rr for the given packet and key.
char * ldns_tsig_keydata_clone(const ldns_tsig_credentials *tc)
#define LDNS_XMALLOC(type, count)
ldns_status ldns_wire2rr(ldns_rr **rr, const uint8_t *wire, size_t max, size_t *pos, ldns_pkt_section section)
converts the data on the uint8_t bytearray (in wire format) to a DNS resource record.
#define LDNS_QDCOUNT(wirebuf)
#define LDNS_NSCOUNT(wirebuf)
#define LDNS_ANCOUNT(wirebuf)
#define LDNS_ARCOUNT(wirebuf)