tsig.c revision 246854
1238104Sdes/* 2238104Sdes * tsig.c 3238104Sdes * 4238104Sdes * contains the functions needed for TSIG [RFC2845] 5238104Sdes * 6238104Sdes * (c) 2005-2006 NLnet Labs 7238104Sdes * See the file LICENSE for the license 8238104Sdes */ 9238104Sdes 10238104Sdes#include <ldns/config.h> 11238104Sdes 12238104Sdes#include <ldns/ldns.h> 13238104Sdes 14238104Sdes#include <strings.h> 15238104Sdes 16238104Sdes#ifdef HAVE_SSL 17238104Sdes#include <openssl/hmac.h> 18238104Sdes#include <openssl/md5.h> 19238104Sdes#endif /* HAVE_SSL */ 20238104Sdes 21238104Sdeschar * 22238104Sdesldns_tsig_algorithm(ldns_tsig_credentials *tc) 23238104Sdes{ 24238104Sdes return tc->algorithm; 25238104Sdes} 26238104Sdes 27238104Sdeschar * 28238104Sdesldns_tsig_keyname(ldns_tsig_credentials *tc) 29238104Sdes{ 30238104Sdes return tc->keyname; 31238104Sdes} 32238104Sdes 33238104Sdeschar * 34238104Sdesldns_tsig_keydata(ldns_tsig_credentials *tc) 35238104Sdes{ 36238104Sdes return tc->keydata; 37238104Sdes} 38238104Sdes 39238104Sdeschar * 40238104Sdesldns_tsig_keyname_clone(ldns_tsig_credentials *tc) 41238104Sdes{ 42238104Sdes return strdup(tc->keyname); 43238104Sdes} 44238104Sdes 45238104Sdeschar * 46238104Sdesldns_tsig_keydata_clone(ldns_tsig_credentials *tc) 47238104Sdes{ 48238104Sdes return strdup(tc->keydata); 49238104Sdes} 50238104Sdes 51238104Sdes/* 52238104Sdes * Makes an exact copy of the wire, but with the tsig rr removed 53238104Sdes */ 54246827Sdesstatic uint8_t * 55238104Sdesldns_tsig_prepare_pkt_wire(uint8_t *wire, size_t wire_len, size_t *result_len) 56238104Sdes{ 57238104Sdes uint8_t *wire2 = NULL; 58238104Sdes uint16_t qd_count; 59238104Sdes uint16_t an_count; 60238104Sdes uint16_t ns_count; 61238104Sdes uint16_t ar_count; 62238104Sdes ldns_rr *rr; 63238104Sdes 64238104Sdes size_t pos; 65238104Sdes uint16_t i; 66238104Sdes 67238104Sdes ldns_status status; 68238104Sdes 69238104Sdes if(wire_len < LDNS_HEADER_SIZE) { 70238104Sdes return NULL; 71238104Sdes } 72238104Sdes /* fake parse the wire */ 73238104Sdes qd_count = LDNS_QDCOUNT(wire); 74238104Sdes an_count = LDNS_ANCOUNT(wire); 75238104Sdes ns_count = LDNS_NSCOUNT(wire); 76238104Sdes ar_count = LDNS_ARCOUNT(wire); 77238104Sdes 78238104Sdes if (ar_count > 0) { 79238104Sdes ar_count--; 80238104Sdes } else { 81238104Sdes return NULL; 82238104Sdes } 83238104Sdes 84238104Sdes pos = LDNS_HEADER_SIZE; 85238104Sdes 86238104Sdes for (i = 0; i < qd_count; i++) { 87238104Sdes status = ldns_wire2rr(&rr, wire, wire_len, &pos, LDNS_SECTION_QUESTION); 88238104Sdes if (status != LDNS_STATUS_OK) { 89238104Sdes return NULL; 90238104Sdes } 91238104Sdes ldns_rr_free(rr); 92238104Sdes } 93238104Sdes 94238104Sdes for (i = 0; i < an_count; i++) { 95238104Sdes status = ldns_wire2rr(&rr, wire, wire_len, &pos, LDNS_SECTION_ANSWER); 96238104Sdes if (status != LDNS_STATUS_OK) { 97238104Sdes return NULL; 98238104Sdes } 99238104Sdes ldns_rr_free(rr); 100238104Sdes } 101238104Sdes 102238104Sdes for (i = 0; i < ns_count; i++) { 103238104Sdes status = ldns_wire2rr(&rr, wire, wire_len, &pos, LDNS_SECTION_AUTHORITY); 104238104Sdes if (status != LDNS_STATUS_OK) { 105238104Sdes return NULL; 106238104Sdes } 107238104Sdes ldns_rr_free(rr); 108238104Sdes } 109238104Sdes 110238104Sdes for (i = 0; i < ar_count; i++) { 111238104Sdes status = ldns_wire2rr(&rr, wire, wire_len, &pos, 112238104Sdes LDNS_SECTION_ADDITIONAL); 113238104Sdes if (status != LDNS_STATUS_OK) { 114238104Sdes return NULL; 115238104Sdes } 116238104Sdes ldns_rr_free(rr); 117238104Sdes } 118238104Sdes 119238104Sdes *result_len = pos; 120238104Sdes wire2 = LDNS_XMALLOC(uint8_t, *result_len); 121238104Sdes if(!wire2) { 122238104Sdes return NULL; 123238104Sdes } 124238104Sdes memcpy(wire2, wire, *result_len); 125238104Sdes 126238104Sdes ldns_write_uint16(wire2 + LDNS_ARCOUNT_OFF, ar_count); 127238104Sdes 128238104Sdes return wire2; 129238104Sdes} 130238104Sdes 131238104Sdes#ifdef HAVE_SSL 132238104Sdesstatic const EVP_MD * 133238104Sdesldns_digest_function(char *name) 134238104Sdes{ 135238104Sdes /* these are the mandatory algorithms from RFC4635 */ 136238104Sdes /* The optional algorithms are not yet implemented */ 137238104Sdes if (strlen(name) == 12 138238104Sdes && strncasecmp(name, "hmac-sha256.", 11) == 0) { 139238104Sdes#ifdef HAVE_EVP_SHA256 140238104Sdes return EVP_sha256(); 141238104Sdes#else 142238104Sdes return NULL; 143238104Sdes#endif 144238104Sdes } else if (strlen(name) == 10 145238104Sdes && strncasecmp(name, "hmac-sha1.", 9) == 0) { 146238104Sdes return EVP_sha1(); 147238104Sdes } else if (strlen(name) == 25 148238104Sdes && strncasecmp(name, "hmac-md5.sig-alg.reg.int.", 25) 149238104Sdes == 0) { 150238104Sdes return EVP_md5(); 151238104Sdes } else { 152238104Sdes return NULL; 153238104Sdes } 154238104Sdes} 155238104Sdes#endif 156238104Sdes 157238104Sdes#ifdef HAVE_SSL 158238104Sdesstatic ldns_status 159238104Sdesldns_tsig_mac_new(ldns_rdf **tsig_mac, uint8_t *pkt_wire, size_t pkt_wire_size, 160238104Sdes const char *key_data, ldns_rdf *key_name_rdf, ldns_rdf *fudge_rdf, 161238104Sdes ldns_rdf *algorithm_rdf, ldns_rdf *time_signed_rdf, ldns_rdf *error_rdf, 162238104Sdes ldns_rdf *other_data_rdf, ldns_rdf *orig_mac_rdf, int tsig_timers_only) 163238104Sdes{ 164238104Sdes ldns_status status; 165238104Sdes char *wireformat; 166238104Sdes int wiresize; 167238104Sdes unsigned char *mac_bytes = NULL; 168238104Sdes unsigned char *key_bytes = NULL; 169238104Sdes int key_size; 170238104Sdes const EVP_MD *digester; 171238104Sdes char *algorithm_name = NULL; 172238104Sdes unsigned int md_len = EVP_MAX_MD_SIZE; 173238104Sdes ldns_rdf *result = NULL; 174238104Sdes ldns_buffer *data_buffer = NULL; 175238104Sdes ldns_rdf *canonical_key_name_rdf = NULL; 176238104Sdes ldns_rdf *canonical_algorithm_rdf = NULL; 177238104Sdes 178238104Sdes if (key_name_rdf == NULL || algorithm_rdf == NULL) { 179238104Sdes return LDNS_STATUS_NULL; 180238104Sdes } 181238104Sdes canonical_key_name_rdf = ldns_rdf_clone(key_name_rdf); 182246854Sdes if (canonical_key_name_rdf == NULL) { 183246854Sdes return LDNS_STATUS_MEM_ERR; 184246854Sdes } 185238104Sdes canonical_algorithm_rdf = ldns_rdf_clone(algorithm_rdf); 186246854Sdes if (canonical_algorithm_rdf == NULL) { 187246854Sdes ldns_rdf_deep_free(canonical_key_name_rdf); 188238104Sdes return LDNS_STATUS_MEM_ERR; 189238104Sdes } 190238104Sdes /* 191238104Sdes * prepare the digestable information 192238104Sdes */ 193238104Sdes data_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN); 194238104Sdes if (!data_buffer) { 195238104Sdes status = LDNS_STATUS_MEM_ERR; 196238104Sdes goto clean; 197238104Sdes } 198238104Sdes /* if orig_mac is not NULL, add it too */ 199238104Sdes if (orig_mac_rdf) { 200238104Sdes (void) ldns_rdf2buffer_wire(data_buffer, orig_mac_rdf); 201238104Sdes } 202238104Sdes ldns_buffer_write(data_buffer, pkt_wire, pkt_wire_size); 203238104Sdes if (!tsig_timers_only) { 204238104Sdes ldns_dname2canonical(canonical_key_name_rdf); 205238104Sdes (void)ldns_rdf2buffer_wire(data_buffer, 206238104Sdes canonical_key_name_rdf); 207238104Sdes ldns_buffer_write_u16(data_buffer, LDNS_RR_CLASS_ANY); 208238104Sdes ldns_buffer_write_u32(data_buffer, 0); 209238104Sdes ldns_dname2canonical(canonical_algorithm_rdf); 210238104Sdes (void)ldns_rdf2buffer_wire(data_buffer, 211238104Sdes canonical_algorithm_rdf); 212238104Sdes } 213238104Sdes (void)ldns_rdf2buffer_wire(data_buffer, time_signed_rdf); 214238104Sdes (void)ldns_rdf2buffer_wire(data_buffer, fudge_rdf); 215238104Sdes if (!tsig_timers_only) { 216238104Sdes (void)ldns_rdf2buffer_wire(data_buffer, error_rdf); 217238104Sdes (void)ldns_rdf2buffer_wire(data_buffer, other_data_rdf); 218238104Sdes } 219238104Sdes 220238104Sdes wireformat = (char *) data_buffer->_data; 221238104Sdes wiresize = (int) ldns_buffer_position(data_buffer); 222238104Sdes 223238104Sdes algorithm_name = ldns_rdf2str(algorithm_rdf); 224238104Sdes if(!algorithm_name) { 225238104Sdes status = LDNS_STATUS_MEM_ERR; 226238104Sdes goto clean; 227238104Sdes } 228238104Sdes 229238104Sdes /* prepare the key */ 230238104Sdes key_bytes = LDNS_XMALLOC(unsigned char, 231238104Sdes ldns_b64_pton_calculate_size(strlen(key_data))); 232238104Sdes if(!key_bytes) { 233238104Sdes status = LDNS_STATUS_MEM_ERR; 234238104Sdes goto clean; 235238104Sdes } 236238104Sdes key_size = ldns_b64_pton(key_data, key_bytes, 237238104Sdes ldns_b64_pton_calculate_size(strlen(key_data))); 238238104Sdes if (key_size < 0) { 239238104Sdes status = LDNS_STATUS_INVALID_B64; 240238104Sdes goto clean; 241238104Sdes } 242238104Sdes /* hmac it */ 243238104Sdes /* 2 spare bytes for the length */ 244238104Sdes mac_bytes = LDNS_XMALLOC(unsigned char, md_len+2); 245238104Sdes if(!mac_bytes) { 246238104Sdes status = LDNS_STATUS_MEM_ERR; 247238104Sdes goto clean; 248238104Sdes } 249238104Sdes memset(mac_bytes, 0, md_len+2); 250238104Sdes 251238104Sdes digester = ldns_digest_function(algorithm_name); 252238104Sdes 253238104Sdes if (digester) { 254238104Sdes (void) HMAC(digester, key_bytes, key_size, (void *)wireformat, 255238104Sdes (size_t) wiresize, mac_bytes + 2, &md_len); 256238104Sdes 257238104Sdes ldns_write_uint16(mac_bytes, md_len); 258238104Sdes result = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_INT16_DATA, md_len + 2, 259238104Sdes mac_bytes); 260238104Sdes } else { 261238104Sdes status = LDNS_STATUS_CRYPTO_UNKNOWN_ALGO; 262238104Sdes goto clean; 263238104Sdes } 264238104Sdes *tsig_mac = result; 265238104Sdes status = LDNS_STATUS_OK; 266238104Sdes clean: 267238104Sdes LDNS_FREE(mac_bytes); 268238104Sdes LDNS_FREE(key_bytes); 269238104Sdes LDNS_FREE(algorithm_name); 270238104Sdes ldns_buffer_free(data_buffer); 271246854Sdes ldns_rdf_deep_free(canonical_algorithm_rdf); 272246854Sdes ldns_rdf_deep_free(canonical_key_name_rdf); 273238104Sdes return status; 274238104Sdes} 275238104Sdes#endif /* HAVE_SSL */ 276238104Sdes 277238104Sdes 278238104Sdes#ifdef HAVE_SSL 279238104Sdesbool 280238104Sdesldns_pkt_tsig_verify(ldns_pkt *pkt, uint8_t *wire, size_t wirelen, const char *key_name, 281238104Sdes const char *key_data, ldns_rdf *orig_mac_rdf) 282238104Sdes{ 283238104Sdes return ldns_pkt_tsig_verify_next(pkt, wire, wirelen, key_name, key_data, orig_mac_rdf, 0); 284238104Sdes} 285238104Sdes 286238104Sdesbool 287238104Sdesldns_pkt_tsig_verify_next(ldns_pkt *pkt, uint8_t *wire, size_t wirelen, const char* key_name, 288238104Sdes const char *key_data, ldns_rdf *orig_mac_rdf, int tsig_timers_only) 289238104Sdes{ 290238104Sdes ldns_rdf *fudge_rdf; 291238104Sdes ldns_rdf *algorithm_rdf; 292238104Sdes ldns_rdf *time_signed_rdf; 293238104Sdes ldns_rdf *orig_id_rdf; 294238104Sdes ldns_rdf *error_rdf; 295238104Sdes ldns_rdf *other_data_rdf; 296238104Sdes ldns_rdf *pkt_mac_rdf; 297238104Sdes ldns_rdf *my_mac_rdf; 298238104Sdes ldns_rdf *key_name_rdf = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, key_name); 299238104Sdes uint16_t pkt_id, orig_pkt_id; 300238104Sdes ldns_status status; 301238104Sdes 302238104Sdes uint8_t *prepared_wire = NULL; 303238104Sdes size_t prepared_wire_size = 0; 304238104Sdes 305238104Sdes ldns_rr *orig_tsig = ldns_pkt_tsig(pkt); 306238104Sdes 307238104Sdes if (!orig_tsig || ldns_rr_rd_count(orig_tsig) <= 6) { 308238104Sdes ldns_rdf_deep_free(key_name_rdf); 309238104Sdes return false; 310238104Sdes } 311238104Sdes algorithm_rdf = ldns_rr_rdf(orig_tsig, 0); 312238104Sdes time_signed_rdf = ldns_rr_rdf(orig_tsig, 1); 313238104Sdes fudge_rdf = ldns_rr_rdf(orig_tsig, 2); 314238104Sdes pkt_mac_rdf = ldns_rr_rdf(orig_tsig, 3); 315238104Sdes orig_id_rdf = ldns_rr_rdf(orig_tsig, 4); 316238104Sdes error_rdf = ldns_rr_rdf(orig_tsig, 5); 317238104Sdes other_data_rdf = ldns_rr_rdf(orig_tsig, 6); 318238104Sdes 319238104Sdes /* remove temporarily */ 320238104Sdes ldns_pkt_set_tsig(pkt, NULL); 321238104Sdes /* temporarily change the id to the original id */ 322238104Sdes pkt_id = ldns_pkt_id(pkt); 323238104Sdes orig_pkt_id = ldns_rdf2native_int16(orig_id_rdf); 324238104Sdes ldns_pkt_set_id(pkt, orig_pkt_id); 325238104Sdes 326238104Sdes prepared_wire = ldns_tsig_prepare_pkt_wire(wire, wirelen, &prepared_wire_size); 327238104Sdes 328238104Sdes status = ldns_tsig_mac_new(&my_mac_rdf, prepared_wire, prepared_wire_size, 329238104Sdes key_data, key_name_rdf, fudge_rdf, algorithm_rdf, 330238104Sdes time_signed_rdf, error_rdf, other_data_rdf, orig_mac_rdf, tsig_timers_only); 331238104Sdes 332238104Sdes LDNS_FREE(prepared_wire); 333238104Sdes 334238104Sdes if (status != LDNS_STATUS_OK) { 335238104Sdes ldns_rdf_deep_free(key_name_rdf); 336238104Sdes return false; 337238104Sdes } 338238104Sdes /* Put back the values */ 339238104Sdes ldns_pkt_set_tsig(pkt, orig_tsig); 340238104Sdes ldns_pkt_set_id(pkt, pkt_id); 341238104Sdes 342238104Sdes ldns_rdf_deep_free(key_name_rdf); 343238104Sdes 344238104Sdes if (ldns_rdf_compare(pkt_mac_rdf, my_mac_rdf) == 0) { 345238104Sdes ldns_rdf_deep_free(my_mac_rdf); 346238104Sdes return true; 347238104Sdes } else { 348238104Sdes ldns_rdf_deep_free(my_mac_rdf); 349238104Sdes return false; 350238104Sdes } 351238104Sdes} 352238104Sdes#endif /* HAVE_SSL */ 353238104Sdes 354238104Sdes#ifdef HAVE_SSL 355238104Sdesldns_status 356238104Sdesldns_pkt_tsig_sign(ldns_pkt *pkt, const char *key_name, const char *key_data, 357238104Sdes uint16_t fudge, const char *algorithm_name, ldns_rdf *query_mac) 358238104Sdes{ 359238104Sdes return ldns_pkt_tsig_sign_next(pkt, key_name, key_data, fudge, algorithm_name, query_mac, 0); 360238104Sdes} 361238104Sdes 362238104Sdesldns_status 363238104Sdesldns_pkt_tsig_sign_next(ldns_pkt *pkt, const char *key_name, const char *key_data, 364238104Sdes uint16_t fudge, const char *algorithm_name, ldns_rdf *query_mac, int tsig_timers_only) 365238104Sdes{ 366238104Sdes ldns_rr *tsig_rr; 367238104Sdes ldns_rdf *key_name_rdf = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, key_name); 368238104Sdes ldns_rdf *fudge_rdf = NULL; 369238104Sdes ldns_rdf *orig_id_rdf = NULL; 370238104Sdes ldns_rdf *algorithm_rdf; 371238104Sdes ldns_rdf *error_rdf = NULL; 372238104Sdes ldns_rdf *mac_rdf = NULL; 373238104Sdes ldns_rdf *other_data_rdf = NULL; 374238104Sdes 375238104Sdes ldns_status status = LDNS_STATUS_OK; 376238104Sdes 377238104Sdes uint8_t *pkt_wire = NULL; 378238104Sdes size_t pkt_wire_len; 379238104Sdes 380238104Sdes struct timeval tv_time_signed; 381238104Sdes uint8_t *time_signed = NULL; 382238104Sdes ldns_rdf *time_signed_rdf = NULL; 383238104Sdes 384238104Sdes algorithm_rdf = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, algorithm_name); 385238104Sdes if(!key_name_rdf || !algorithm_rdf) { 386238104Sdes status = LDNS_STATUS_MEM_ERR; 387238104Sdes goto clean; 388238104Sdes } 389238104Sdes 390238104Sdes /* eww don't have create tsigtime rdf yet :( */ 391238104Sdes /* bleh :p */ 392238104Sdes if (gettimeofday(&tv_time_signed, NULL) == 0) { 393238104Sdes time_signed = LDNS_XMALLOC(uint8_t, 6); 394238104Sdes if(!time_signed) { 395238104Sdes status = LDNS_STATUS_MEM_ERR; 396238104Sdes goto clean; 397238104Sdes } 398238104Sdes ldns_write_uint64_as_uint48(time_signed, 399238104Sdes (uint64_t)tv_time_signed.tv_sec); 400238104Sdes } else { 401238104Sdes status = LDNS_STATUS_INTERNAL_ERR; 402238104Sdes goto clean; 403238104Sdes } 404238104Sdes 405238104Sdes time_signed_rdf = ldns_rdf_new(LDNS_RDF_TYPE_TSIGTIME, 6, time_signed); 406238104Sdes if(!time_signed_rdf) { 407238104Sdes LDNS_FREE(time_signed); 408238104Sdes status = LDNS_STATUS_MEM_ERR; 409238104Sdes goto clean; 410238104Sdes } 411238104Sdes 412238104Sdes fudge_rdf = ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16, fudge); 413238104Sdes 414238104Sdes orig_id_rdf = ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16, ldns_pkt_id(pkt)); 415238104Sdes 416238104Sdes error_rdf = ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16, 0); 417238104Sdes 418238104Sdes other_data_rdf = ldns_native2rdf_int16_data(0, NULL); 419238104Sdes 420238104Sdes if(!fudge_rdf || !orig_id_rdf || !error_rdf || !other_data_rdf) { 421238104Sdes status = LDNS_STATUS_MEM_ERR; 422238104Sdes goto clean; 423238104Sdes } 424238104Sdes 425238104Sdes if (ldns_pkt2wire(&pkt_wire, pkt, &pkt_wire_len) != LDNS_STATUS_OK) { 426238104Sdes status = LDNS_STATUS_ERR; 427238104Sdes goto clean; 428238104Sdes } 429238104Sdes 430238104Sdes status = ldns_tsig_mac_new(&mac_rdf, pkt_wire, pkt_wire_len, 431238104Sdes key_data, key_name_rdf, fudge_rdf, algorithm_rdf, 432238104Sdes time_signed_rdf, error_rdf, other_data_rdf, query_mac, tsig_timers_only); 433238104Sdes 434238104Sdes if (!mac_rdf) { 435238104Sdes goto clean; 436238104Sdes } 437238104Sdes 438238104Sdes LDNS_FREE(pkt_wire); 439238104Sdes 440238104Sdes /* Create the TSIG RR */ 441238104Sdes tsig_rr = ldns_rr_new(); 442238104Sdes if(!tsig_rr) { 443238104Sdes status = LDNS_STATUS_MEM_ERR; 444238104Sdes goto clean; 445238104Sdes } 446238104Sdes ldns_rr_set_owner(tsig_rr, key_name_rdf); 447238104Sdes ldns_rr_set_class(tsig_rr, LDNS_RR_CLASS_ANY); 448238104Sdes ldns_rr_set_type(tsig_rr, LDNS_RR_TYPE_TSIG); 449238104Sdes ldns_rr_set_ttl(tsig_rr, 0); 450238104Sdes 451238104Sdes ldns_rr_push_rdf(tsig_rr, algorithm_rdf); 452238104Sdes ldns_rr_push_rdf(tsig_rr, time_signed_rdf); 453238104Sdes ldns_rr_push_rdf(tsig_rr, fudge_rdf); 454238104Sdes ldns_rr_push_rdf(tsig_rr, mac_rdf); 455238104Sdes ldns_rr_push_rdf(tsig_rr, orig_id_rdf); 456238104Sdes ldns_rr_push_rdf(tsig_rr, error_rdf); 457238104Sdes ldns_rr_push_rdf(tsig_rr, other_data_rdf); 458238104Sdes 459238104Sdes ldns_pkt_set_tsig(pkt, tsig_rr); 460238104Sdes 461238104Sdes return status; 462238104Sdes 463238104Sdes clean: 464238104Sdes LDNS_FREE(pkt_wire); 465238104Sdes ldns_rdf_free(key_name_rdf); 466238104Sdes ldns_rdf_free(algorithm_rdf); 467238104Sdes ldns_rdf_free(time_signed_rdf); 468238104Sdes ldns_rdf_free(fudge_rdf); 469238104Sdes ldns_rdf_free(orig_id_rdf); 470238104Sdes ldns_rdf_free(error_rdf); 471238104Sdes ldns_rdf_free(other_data_rdf); 472238104Sdes return status; 473238104Sdes} 474238104Sdes#endif /* HAVE_SSL */ 475