1*825eb42bSJan Lentfer /* 2*825eb42bSJan Lentfer * rr_function.c 3*825eb42bSJan Lentfer * 4*825eb42bSJan Lentfer * function that operate on specific rr types 5*825eb42bSJan Lentfer * 6*825eb42bSJan Lentfer * (c) NLnet Labs, 2004-2006 7*825eb42bSJan Lentfer * See the file LICENSE for the license 8*825eb42bSJan Lentfer */ 9*825eb42bSJan Lentfer 10*825eb42bSJan Lentfer /* 11*825eb42bSJan Lentfer * These come strait from perldoc Net::DNS::RR::xxx 12*825eb42bSJan Lentfer * first the read variant, then the write. This is 13*825eb42bSJan Lentfer * not complete. 14*825eb42bSJan Lentfer */ 15*825eb42bSJan Lentfer 16*825eb42bSJan Lentfer #include <ldns/config.h> 17*825eb42bSJan Lentfer 18*825eb42bSJan Lentfer #include <ldns/ldns.h> 19*825eb42bSJan Lentfer 20*825eb42bSJan Lentfer #include <limits.h> 21*825eb42bSJan Lentfer #include <strings.h> 22*825eb42bSJan Lentfer 23*825eb42bSJan Lentfer /** 24*825eb42bSJan Lentfer * return a specific rdf 25*825eb42bSJan Lentfer * \param[in] type type of RR 26*825eb42bSJan Lentfer * \param[in] rr the rr itself 27*825eb42bSJan Lentfer * \param[in] pos at which postion to get it 28*825eb42bSJan Lentfer * \return the rdf sought 29*825eb42bSJan Lentfer */ 30*825eb42bSJan Lentfer static ldns_rdf * 31*825eb42bSJan Lentfer ldns_rr_function(ldns_rr_type type, const ldns_rr *rr, size_t pos) 32*825eb42bSJan Lentfer { 33*825eb42bSJan Lentfer if (!rr || ldns_rr_get_type(rr) != type) { 34*825eb42bSJan Lentfer return NULL; 35*825eb42bSJan Lentfer } 36*825eb42bSJan Lentfer return ldns_rr_rdf(rr, pos); 37*825eb42bSJan Lentfer } 38*825eb42bSJan Lentfer 39*825eb42bSJan Lentfer /** 40*825eb42bSJan Lentfer * set a specific rdf 41*825eb42bSJan Lentfer * \param[in] type type of RR 42*825eb42bSJan Lentfer * \param[in] rr the rr itself 43*825eb42bSJan Lentfer * \param[in] rdf the rdf to set 44*825eb42bSJan Lentfer * \param[in] pos at which postion to set it 45*825eb42bSJan Lentfer * \return true or false 46*825eb42bSJan Lentfer */ 47*825eb42bSJan Lentfer static bool 48*825eb42bSJan Lentfer ldns_rr_set_function(ldns_rr_type type, ldns_rr *rr, ldns_rdf *rdf, size_t pos) 49*825eb42bSJan Lentfer { 50*825eb42bSJan Lentfer ldns_rdf *pop; 51*825eb42bSJan Lentfer if (!rr || ldns_rr_get_type(rr) != type) { 52*825eb42bSJan Lentfer return false; 53*825eb42bSJan Lentfer } 54*825eb42bSJan Lentfer pop = ldns_rr_set_rdf(rr, rdf, pos); 55*825eb42bSJan Lentfer ldns_rdf_deep_free(pop); 56*825eb42bSJan Lentfer return true; 57*825eb42bSJan Lentfer } 58*825eb42bSJan Lentfer 59*825eb42bSJan Lentfer /* A/AAAA records */ 60*825eb42bSJan Lentfer ldns_rdf * 61*825eb42bSJan Lentfer ldns_rr_a_address(const ldns_rr *r) 62*825eb42bSJan Lentfer { 63*825eb42bSJan Lentfer /* 2 types to check, cannot use the macro */ 64*825eb42bSJan Lentfer if (!r || (ldns_rr_get_type(r) != LDNS_RR_TYPE_A && 65*825eb42bSJan Lentfer ldns_rr_get_type(r) != LDNS_RR_TYPE_AAAA)) { 66*825eb42bSJan Lentfer return NULL; 67*825eb42bSJan Lentfer } 68*825eb42bSJan Lentfer return ldns_rr_rdf(r, 0); 69*825eb42bSJan Lentfer } 70*825eb42bSJan Lentfer 71*825eb42bSJan Lentfer bool 72*825eb42bSJan Lentfer ldns_rr_a_set_address(ldns_rr *r, ldns_rdf *f) 73*825eb42bSJan Lentfer { 74*825eb42bSJan Lentfer /* 2 types to check, cannot use the macro... */ 75*825eb42bSJan Lentfer ldns_rdf *pop; 76*825eb42bSJan Lentfer if (!r || (ldns_rr_get_type(r) != LDNS_RR_TYPE_A && 77*825eb42bSJan Lentfer ldns_rr_get_type(r) != LDNS_RR_TYPE_AAAA)) { 78*825eb42bSJan Lentfer return false; 79*825eb42bSJan Lentfer } 80*825eb42bSJan Lentfer pop = ldns_rr_set_rdf(r, f, 0); 81*825eb42bSJan Lentfer if (pop) { 82*825eb42bSJan Lentfer LDNS_FREE(pop); 83*825eb42bSJan Lentfer return true; 84*825eb42bSJan Lentfer } else { 85*825eb42bSJan Lentfer return false; 86*825eb42bSJan Lentfer } 87*825eb42bSJan Lentfer } 88*825eb42bSJan Lentfer 89*825eb42bSJan Lentfer /* NS record */ 90*825eb42bSJan Lentfer ldns_rdf * 91*825eb42bSJan Lentfer ldns_rr_ns_nsdname(const ldns_rr *r) 92*825eb42bSJan Lentfer { 93*825eb42bSJan Lentfer return ldns_rr_function(LDNS_RR_TYPE_NS, r, 0); 94*825eb42bSJan Lentfer } 95*825eb42bSJan Lentfer 96*825eb42bSJan Lentfer /* MX record */ 97*825eb42bSJan Lentfer ldns_rdf * 98*825eb42bSJan Lentfer ldns_rr_mx_preference(const ldns_rr *r) 99*825eb42bSJan Lentfer { 100*825eb42bSJan Lentfer return ldns_rr_function(LDNS_RR_TYPE_MX, r, 0); 101*825eb42bSJan Lentfer } 102*825eb42bSJan Lentfer 103*825eb42bSJan Lentfer ldns_rdf * 104*825eb42bSJan Lentfer ldns_rr_mx_exchange(const ldns_rr *r) 105*825eb42bSJan Lentfer { 106*825eb42bSJan Lentfer return ldns_rr_function(LDNS_RR_TYPE_MX, r, 1); 107*825eb42bSJan Lentfer } 108*825eb42bSJan Lentfer 109*825eb42bSJan Lentfer /* RRSIG record */ 110*825eb42bSJan Lentfer ldns_rdf * 111*825eb42bSJan Lentfer ldns_rr_rrsig_typecovered(const ldns_rr *r) 112*825eb42bSJan Lentfer { 113*825eb42bSJan Lentfer return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 0); 114*825eb42bSJan Lentfer } 115*825eb42bSJan Lentfer 116*825eb42bSJan Lentfer bool 117*825eb42bSJan Lentfer ldns_rr_rrsig_set_typecovered(ldns_rr *r, ldns_rdf *f) 118*825eb42bSJan Lentfer { 119*825eb42bSJan Lentfer return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 0); 120*825eb42bSJan Lentfer } 121*825eb42bSJan Lentfer 122*825eb42bSJan Lentfer ldns_rdf * 123*825eb42bSJan Lentfer ldns_rr_rrsig_algorithm(const ldns_rr *r) 124*825eb42bSJan Lentfer { 125*825eb42bSJan Lentfer return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 1); 126*825eb42bSJan Lentfer } 127*825eb42bSJan Lentfer 128*825eb42bSJan Lentfer bool 129*825eb42bSJan Lentfer ldns_rr_rrsig_set_algorithm(ldns_rr *r, ldns_rdf *f) 130*825eb42bSJan Lentfer { 131*825eb42bSJan Lentfer return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 1); 132*825eb42bSJan Lentfer } 133*825eb42bSJan Lentfer 134*825eb42bSJan Lentfer ldns_rdf * 135*825eb42bSJan Lentfer ldns_rr_rrsig_labels(const ldns_rr *r) 136*825eb42bSJan Lentfer { 137*825eb42bSJan Lentfer return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 2); 138*825eb42bSJan Lentfer } 139*825eb42bSJan Lentfer 140*825eb42bSJan Lentfer bool 141*825eb42bSJan Lentfer ldns_rr_rrsig_set_labels(ldns_rr *r, ldns_rdf *f) 142*825eb42bSJan Lentfer { 143*825eb42bSJan Lentfer return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 2); 144*825eb42bSJan Lentfer } 145*825eb42bSJan Lentfer 146*825eb42bSJan Lentfer ldns_rdf * 147*825eb42bSJan Lentfer ldns_rr_rrsig_origttl(const ldns_rr *r) 148*825eb42bSJan Lentfer { 149*825eb42bSJan Lentfer return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 3); 150*825eb42bSJan Lentfer } 151*825eb42bSJan Lentfer 152*825eb42bSJan Lentfer bool 153*825eb42bSJan Lentfer ldns_rr_rrsig_set_origttl(ldns_rr *r, ldns_rdf *f) 154*825eb42bSJan Lentfer { 155*825eb42bSJan Lentfer return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 3); 156*825eb42bSJan Lentfer } 157*825eb42bSJan Lentfer 158*825eb42bSJan Lentfer ldns_rdf * 159*825eb42bSJan Lentfer ldns_rr_rrsig_expiration(const ldns_rr *r) 160*825eb42bSJan Lentfer { 161*825eb42bSJan Lentfer return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 4); 162*825eb42bSJan Lentfer } 163*825eb42bSJan Lentfer 164*825eb42bSJan Lentfer bool 165*825eb42bSJan Lentfer ldns_rr_rrsig_set_expiration(ldns_rr *r, ldns_rdf *f) 166*825eb42bSJan Lentfer { 167*825eb42bSJan Lentfer return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 4); 168*825eb42bSJan Lentfer } 169*825eb42bSJan Lentfer 170*825eb42bSJan Lentfer ldns_rdf * 171*825eb42bSJan Lentfer ldns_rr_rrsig_inception(const ldns_rr *r) 172*825eb42bSJan Lentfer { 173*825eb42bSJan Lentfer return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 5); 174*825eb42bSJan Lentfer } 175*825eb42bSJan Lentfer 176*825eb42bSJan Lentfer bool 177*825eb42bSJan Lentfer ldns_rr_rrsig_set_inception(ldns_rr *r, ldns_rdf *f) 178*825eb42bSJan Lentfer { 179*825eb42bSJan Lentfer return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 5); 180*825eb42bSJan Lentfer } 181*825eb42bSJan Lentfer 182*825eb42bSJan Lentfer ldns_rdf * 183*825eb42bSJan Lentfer ldns_rr_rrsig_keytag(const ldns_rr *r) 184*825eb42bSJan Lentfer { 185*825eb42bSJan Lentfer return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 6); 186*825eb42bSJan Lentfer } 187*825eb42bSJan Lentfer 188*825eb42bSJan Lentfer bool 189*825eb42bSJan Lentfer ldns_rr_rrsig_set_keytag(ldns_rr *r, ldns_rdf *f) 190*825eb42bSJan Lentfer { 191*825eb42bSJan Lentfer return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 6); 192*825eb42bSJan Lentfer } 193*825eb42bSJan Lentfer 194*825eb42bSJan Lentfer ldns_rdf * 195*825eb42bSJan Lentfer ldns_rr_rrsig_signame(const ldns_rr *r) 196*825eb42bSJan Lentfer { 197*825eb42bSJan Lentfer return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 7); 198*825eb42bSJan Lentfer } 199*825eb42bSJan Lentfer 200*825eb42bSJan Lentfer bool 201*825eb42bSJan Lentfer ldns_rr_rrsig_set_signame(ldns_rr *r, ldns_rdf *f) 202*825eb42bSJan Lentfer { 203*825eb42bSJan Lentfer return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 7); 204*825eb42bSJan Lentfer } 205*825eb42bSJan Lentfer 206*825eb42bSJan Lentfer ldns_rdf * 207*825eb42bSJan Lentfer ldns_rr_rrsig_sig(const ldns_rr *r) 208*825eb42bSJan Lentfer { 209*825eb42bSJan Lentfer return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 8); 210*825eb42bSJan Lentfer } 211*825eb42bSJan Lentfer 212*825eb42bSJan Lentfer bool 213*825eb42bSJan Lentfer ldns_rr_rrsig_set_sig(ldns_rr *r, ldns_rdf *f) 214*825eb42bSJan Lentfer { 215*825eb42bSJan Lentfer return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 8); 216*825eb42bSJan Lentfer } 217*825eb42bSJan Lentfer 218*825eb42bSJan Lentfer /* DNSKEY record */ 219*825eb42bSJan Lentfer ldns_rdf * 220*825eb42bSJan Lentfer ldns_rr_dnskey_flags(const ldns_rr *r) 221*825eb42bSJan Lentfer { 222*825eb42bSJan Lentfer return ldns_rr_function(LDNS_RR_TYPE_DNSKEY, r, 0); 223*825eb42bSJan Lentfer } 224*825eb42bSJan Lentfer 225*825eb42bSJan Lentfer bool 226*825eb42bSJan Lentfer ldns_rr_dnskey_set_flags(ldns_rr *r, ldns_rdf *f) 227*825eb42bSJan Lentfer { 228*825eb42bSJan Lentfer return ldns_rr_set_function(LDNS_RR_TYPE_DNSKEY, r, f, 0); 229*825eb42bSJan Lentfer } 230*825eb42bSJan Lentfer 231*825eb42bSJan Lentfer ldns_rdf * 232*825eb42bSJan Lentfer ldns_rr_dnskey_protocol(const ldns_rr *r) 233*825eb42bSJan Lentfer { 234*825eb42bSJan Lentfer return ldns_rr_function(LDNS_RR_TYPE_DNSKEY, r, 1); 235*825eb42bSJan Lentfer } 236*825eb42bSJan Lentfer 237*825eb42bSJan Lentfer bool 238*825eb42bSJan Lentfer ldns_rr_dnskey_set_protocol(ldns_rr *r, ldns_rdf *f) 239*825eb42bSJan Lentfer { 240*825eb42bSJan Lentfer return ldns_rr_set_function(LDNS_RR_TYPE_DNSKEY, r, f, 1); 241*825eb42bSJan Lentfer } 242*825eb42bSJan Lentfer 243*825eb42bSJan Lentfer ldns_rdf * 244*825eb42bSJan Lentfer ldns_rr_dnskey_algorithm(const ldns_rr *r) 245*825eb42bSJan Lentfer { 246*825eb42bSJan Lentfer return ldns_rr_function(LDNS_RR_TYPE_DNSKEY, r, 2); 247*825eb42bSJan Lentfer } 248*825eb42bSJan Lentfer 249*825eb42bSJan Lentfer bool 250*825eb42bSJan Lentfer ldns_rr_dnskey_set_algorithm(ldns_rr *r, ldns_rdf *f) 251*825eb42bSJan Lentfer { 252*825eb42bSJan Lentfer return ldns_rr_set_function(LDNS_RR_TYPE_DNSKEY, r, f, 2); 253*825eb42bSJan Lentfer } 254*825eb42bSJan Lentfer 255*825eb42bSJan Lentfer ldns_rdf * 256*825eb42bSJan Lentfer ldns_rr_dnskey_key(const ldns_rr *r) 257*825eb42bSJan Lentfer { 258*825eb42bSJan Lentfer return ldns_rr_function(LDNS_RR_TYPE_DNSKEY, r, 3); 259*825eb42bSJan Lentfer } 260*825eb42bSJan Lentfer 261*825eb42bSJan Lentfer bool 262*825eb42bSJan Lentfer ldns_rr_dnskey_set_key(ldns_rr *r, ldns_rdf *f) 263*825eb42bSJan Lentfer { 264*825eb42bSJan Lentfer return ldns_rr_set_function(LDNS_RR_TYPE_DNSKEY, r, f, 3); 265*825eb42bSJan Lentfer } 266*825eb42bSJan Lentfer 267*825eb42bSJan Lentfer size_t 268*825eb42bSJan Lentfer ldns_rr_dnskey_key_size_raw(const unsigned char* keydata, 269*825eb42bSJan Lentfer const size_t len, 270*825eb42bSJan Lentfer const ldns_algorithm alg) 271*825eb42bSJan Lentfer { 272*825eb42bSJan Lentfer /* for DSA keys */ 273*825eb42bSJan Lentfer uint8_t t; 274*825eb42bSJan Lentfer 275*825eb42bSJan Lentfer /* for RSA keys */ 276*825eb42bSJan Lentfer uint16_t exp; 277*825eb42bSJan Lentfer uint16_t int16; 278*825eb42bSJan Lentfer 279*825eb42bSJan Lentfer switch (alg) { 280*825eb42bSJan Lentfer case LDNS_SIGN_DSA: 281*825eb42bSJan Lentfer case LDNS_SIGN_DSA_NSEC3: 282*825eb42bSJan Lentfer if (len > 0) { 283*825eb42bSJan Lentfer t = keydata[0]; 284*825eb42bSJan Lentfer return (64 + t*8)*8; 285*825eb42bSJan Lentfer } else { 286*825eb42bSJan Lentfer return 0; 287*825eb42bSJan Lentfer } 288*825eb42bSJan Lentfer break; 289*825eb42bSJan Lentfer case LDNS_SIGN_RSAMD5: 290*825eb42bSJan Lentfer case LDNS_SIGN_RSASHA1: 291*825eb42bSJan Lentfer case LDNS_SIGN_RSASHA1_NSEC3: 292*825eb42bSJan Lentfer #ifdef USE_SHA2 293*825eb42bSJan Lentfer case LDNS_SIGN_RSASHA256: 294*825eb42bSJan Lentfer case LDNS_SIGN_RSASHA512: 295*825eb42bSJan Lentfer #endif 296*825eb42bSJan Lentfer if (len > 0) { 297*825eb42bSJan Lentfer if (keydata[0] == 0) { 298*825eb42bSJan Lentfer /* big exponent */ 299*825eb42bSJan Lentfer if (len > 3) { 300*825eb42bSJan Lentfer memmove(&int16, keydata + 1, 2); 301*825eb42bSJan Lentfer exp = ntohs(int16); 302*825eb42bSJan Lentfer return (len - exp - 3)*8; 303*825eb42bSJan Lentfer } else { 304*825eb42bSJan Lentfer return 0; 305*825eb42bSJan Lentfer } 306*825eb42bSJan Lentfer } else { 307*825eb42bSJan Lentfer exp = keydata[0]; 308*825eb42bSJan Lentfer return (len-exp-1)*8; 309*825eb42bSJan Lentfer } 310*825eb42bSJan Lentfer } else { 311*825eb42bSJan Lentfer return 0; 312*825eb42bSJan Lentfer } 313*825eb42bSJan Lentfer break; 314*825eb42bSJan Lentfer #ifdef USE_GOST 315*825eb42bSJan Lentfer case LDNS_SIGN_GOST: 316*825eb42bSJan Lentfer return 512; 317*825eb42bSJan Lentfer break; 318*825eb42bSJan Lentfer #endif 319*825eb42bSJan Lentfer case LDNS_SIGN_HMACMD5: 320*825eb42bSJan Lentfer return len; 321*825eb42bSJan Lentfer break; 322*825eb42bSJan Lentfer default: 323*825eb42bSJan Lentfer return 0; 324*825eb42bSJan Lentfer } 325*825eb42bSJan Lentfer } 326*825eb42bSJan Lentfer 327*825eb42bSJan Lentfer size_t 328*825eb42bSJan Lentfer ldns_rr_dnskey_key_size(const ldns_rr *key) 329*825eb42bSJan Lentfer { 330*825eb42bSJan Lentfer if (!key) { 331*825eb42bSJan Lentfer return 0; 332*825eb42bSJan Lentfer } 333*825eb42bSJan Lentfer return ldns_rr_dnskey_key_size_raw(ldns_rdf_data(ldns_rr_dnskey_key(key)), 334*825eb42bSJan Lentfer ldns_rdf_size(ldns_rr_dnskey_key(key)), 335*825eb42bSJan Lentfer ldns_rdf2native_int8(ldns_rr_dnskey_algorithm(key)) 336*825eb42bSJan Lentfer ); 337*825eb42bSJan Lentfer } 338