1*7b5038d7SDag-Erling Smørgrav /* 2*7b5038d7SDag-Erling Smørgrav * dnssec.c 3*7b5038d7SDag-Erling Smørgrav * 4*7b5038d7SDag-Erling Smørgrav * contains the cryptographic function needed for DNSSEC in ldns 5*7b5038d7SDag-Erling Smørgrav * The crypto library used is openssl 6*7b5038d7SDag-Erling Smørgrav * 7*7b5038d7SDag-Erling Smørgrav * (c) NLnet Labs, 2004-2008 8*7b5038d7SDag-Erling Smørgrav * 9*7b5038d7SDag-Erling Smørgrav * See the file LICENSE for the license 10*7b5038d7SDag-Erling Smørgrav */ 11*7b5038d7SDag-Erling Smørgrav 12*7b5038d7SDag-Erling Smørgrav #include <ldns/config.h> 13*7b5038d7SDag-Erling Smørgrav 14*7b5038d7SDag-Erling Smørgrav #include <ldns/ldns.h> 15*7b5038d7SDag-Erling Smørgrav #include <ldns/dnssec.h> 16*7b5038d7SDag-Erling Smørgrav 17*7b5038d7SDag-Erling Smørgrav #include <strings.h> 18*7b5038d7SDag-Erling Smørgrav #include <time.h> 19*7b5038d7SDag-Erling Smørgrav 20*7b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 21*7b5038d7SDag-Erling Smørgrav #include <openssl/ssl.h> 22*7b5038d7SDag-Erling Smørgrav #include <openssl/evp.h> 23*7b5038d7SDag-Erling Smørgrav #include <openssl/rand.h> 24*7b5038d7SDag-Erling Smørgrav #include <openssl/err.h> 25*7b5038d7SDag-Erling Smørgrav #include <openssl/md5.h> 26*7b5038d7SDag-Erling Smørgrav #endif 27*7b5038d7SDag-Erling Smørgrav 28*7b5038d7SDag-Erling Smørgrav ldns_rr * 29*7b5038d7SDag-Erling Smørgrav ldns_dnssec_get_rrsig_for_name_and_type(const ldns_rdf *name, 30*7b5038d7SDag-Erling Smørgrav const ldns_rr_type type, 31*7b5038d7SDag-Erling Smørgrav const ldns_rr_list *rrs) 32*7b5038d7SDag-Erling Smørgrav { 33*7b5038d7SDag-Erling Smørgrav size_t i; 34*7b5038d7SDag-Erling Smørgrav ldns_rr *candidate; 35*7b5038d7SDag-Erling Smørgrav 36*7b5038d7SDag-Erling Smørgrav if (!name || !rrs) { 37*7b5038d7SDag-Erling Smørgrav return NULL; 38*7b5038d7SDag-Erling Smørgrav } 39*7b5038d7SDag-Erling Smørgrav 40*7b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(rrs); i++) { 41*7b5038d7SDag-Erling Smørgrav candidate = ldns_rr_list_rr(rrs, i); 42*7b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(candidate) == LDNS_RR_TYPE_RRSIG) { 43*7b5038d7SDag-Erling Smørgrav if (ldns_dname_compare(ldns_rr_owner(candidate), 44*7b5038d7SDag-Erling Smørgrav name) == 0 && 45*7b5038d7SDag-Erling Smørgrav ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(candidate)) 46*7b5038d7SDag-Erling Smørgrav == type 47*7b5038d7SDag-Erling Smørgrav ) { 48*7b5038d7SDag-Erling Smørgrav return candidate; 49*7b5038d7SDag-Erling Smørgrav } 50*7b5038d7SDag-Erling Smørgrav } 51*7b5038d7SDag-Erling Smørgrav } 52*7b5038d7SDag-Erling Smørgrav 53*7b5038d7SDag-Erling Smørgrav return NULL; 54*7b5038d7SDag-Erling Smørgrav } 55*7b5038d7SDag-Erling Smørgrav 56*7b5038d7SDag-Erling Smørgrav ldns_rr * 57*7b5038d7SDag-Erling Smørgrav ldns_dnssec_get_dnskey_for_rrsig(const ldns_rr *rrsig, 58*7b5038d7SDag-Erling Smørgrav const ldns_rr_list *rrs) 59*7b5038d7SDag-Erling Smørgrav { 60*7b5038d7SDag-Erling Smørgrav size_t i; 61*7b5038d7SDag-Erling Smørgrav ldns_rr *candidate; 62*7b5038d7SDag-Erling Smørgrav 63*7b5038d7SDag-Erling Smørgrav if (!rrsig || !rrs) { 64*7b5038d7SDag-Erling Smørgrav return NULL; 65*7b5038d7SDag-Erling Smørgrav } 66*7b5038d7SDag-Erling Smørgrav 67*7b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(rrs); i++) { 68*7b5038d7SDag-Erling Smørgrav candidate = ldns_rr_list_rr(rrs, i); 69*7b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(candidate) == LDNS_RR_TYPE_DNSKEY) { 70*7b5038d7SDag-Erling Smørgrav if (ldns_dname_compare(ldns_rr_owner(candidate), 71*7b5038d7SDag-Erling Smørgrav ldns_rr_rrsig_signame(rrsig)) == 0 && 72*7b5038d7SDag-Erling Smørgrav ldns_rdf2native_int16(ldns_rr_rrsig_keytag(rrsig)) == 73*7b5038d7SDag-Erling Smørgrav ldns_calc_keytag(candidate) 74*7b5038d7SDag-Erling Smørgrav ) { 75*7b5038d7SDag-Erling Smørgrav return candidate; 76*7b5038d7SDag-Erling Smørgrav } 77*7b5038d7SDag-Erling Smørgrav } 78*7b5038d7SDag-Erling Smørgrav } 79*7b5038d7SDag-Erling Smørgrav 80*7b5038d7SDag-Erling Smørgrav return NULL; 81*7b5038d7SDag-Erling Smørgrav } 82*7b5038d7SDag-Erling Smørgrav 83*7b5038d7SDag-Erling Smørgrav ldns_rdf * 84*7b5038d7SDag-Erling Smørgrav ldns_nsec_get_bitmap(ldns_rr *nsec) { 85*7b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(nsec) == LDNS_RR_TYPE_NSEC) { 86*7b5038d7SDag-Erling Smørgrav return ldns_rr_rdf(nsec, 1); 87*7b5038d7SDag-Erling Smørgrav } else if (ldns_rr_get_type(nsec) == LDNS_RR_TYPE_NSEC3) { 88*7b5038d7SDag-Erling Smørgrav return ldns_rr_rdf(nsec, 5); 89*7b5038d7SDag-Erling Smørgrav } else { 90*7b5038d7SDag-Erling Smørgrav return NULL; 91*7b5038d7SDag-Erling Smørgrav } 92*7b5038d7SDag-Erling Smørgrav } 93*7b5038d7SDag-Erling Smørgrav 94*7b5038d7SDag-Erling Smørgrav /*return the owner name of the closest encloser for name from the list of rrs */ 95*7b5038d7SDag-Erling Smørgrav /* this is NOT the hash, but the original name! */ 96*7b5038d7SDag-Erling Smørgrav ldns_rdf * 97*7b5038d7SDag-Erling Smørgrav ldns_dnssec_nsec3_closest_encloser(ldns_rdf *qname, 98*7b5038d7SDag-Erling Smørgrav ATTR_UNUSED(ldns_rr_type qtype), 99*7b5038d7SDag-Erling Smørgrav ldns_rr_list *nsec3s) 100*7b5038d7SDag-Erling Smørgrav { 101*7b5038d7SDag-Erling Smørgrav /* remember parameters, they must match */ 102*7b5038d7SDag-Erling Smørgrav uint8_t algorithm; 103*7b5038d7SDag-Erling Smørgrav uint32_t iterations; 104*7b5038d7SDag-Erling Smørgrav uint8_t salt_length; 105*7b5038d7SDag-Erling Smørgrav uint8_t *salt; 106*7b5038d7SDag-Erling Smørgrav 107*7b5038d7SDag-Erling Smørgrav ldns_rdf *sname, *hashed_sname, *tmp; 108*7b5038d7SDag-Erling Smørgrav bool flag; 109*7b5038d7SDag-Erling Smørgrav 110*7b5038d7SDag-Erling Smørgrav bool exact_match_found; 111*7b5038d7SDag-Erling Smørgrav bool in_range_found; 112*7b5038d7SDag-Erling Smørgrav 113*7b5038d7SDag-Erling Smørgrav ldns_status status; 114*7b5038d7SDag-Erling Smørgrav ldns_rdf *zone_name; 115*7b5038d7SDag-Erling Smørgrav 116*7b5038d7SDag-Erling Smørgrav size_t nsec_i; 117*7b5038d7SDag-Erling Smørgrav ldns_rr *nsec; 118*7b5038d7SDag-Erling Smørgrav ldns_rdf *result = NULL; 119*7b5038d7SDag-Erling Smørgrav 120*7b5038d7SDag-Erling Smørgrav if (!qname || !nsec3s || ldns_rr_list_rr_count(nsec3s) < 1) { 121*7b5038d7SDag-Erling Smørgrav return NULL; 122*7b5038d7SDag-Erling Smørgrav } 123*7b5038d7SDag-Erling Smørgrav 124*7b5038d7SDag-Erling Smørgrav nsec = ldns_rr_list_rr(nsec3s, 0); 125*7b5038d7SDag-Erling Smørgrav algorithm = ldns_nsec3_algorithm(nsec); 126*7b5038d7SDag-Erling Smørgrav salt_length = ldns_nsec3_salt_length(nsec); 127*7b5038d7SDag-Erling Smørgrav salt = ldns_nsec3_salt_data(nsec); 128*7b5038d7SDag-Erling Smørgrav iterations = ldns_nsec3_iterations(nsec); 129*7b5038d7SDag-Erling Smørgrav 130*7b5038d7SDag-Erling Smørgrav sname = ldns_rdf_clone(qname); 131*7b5038d7SDag-Erling Smørgrav 132*7b5038d7SDag-Erling Smørgrav flag = false; 133*7b5038d7SDag-Erling Smørgrav 134*7b5038d7SDag-Erling Smørgrav zone_name = ldns_dname_left_chop(ldns_rr_owner(nsec)); 135*7b5038d7SDag-Erling Smørgrav 136*7b5038d7SDag-Erling Smørgrav /* algorithm from nsec3-07 8.3 */ 137*7b5038d7SDag-Erling Smørgrav while (ldns_dname_label_count(sname) > 0) { 138*7b5038d7SDag-Erling Smørgrav exact_match_found = false; 139*7b5038d7SDag-Erling Smørgrav in_range_found = false; 140*7b5038d7SDag-Erling Smørgrav 141*7b5038d7SDag-Erling Smørgrav hashed_sname = ldns_nsec3_hash_name(sname, 142*7b5038d7SDag-Erling Smørgrav algorithm, 143*7b5038d7SDag-Erling Smørgrav iterations, 144*7b5038d7SDag-Erling Smørgrav salt_length, 145*7b5038d7SDag-Erling Smørgrav salt); 146*7b5038d7SDag-Erling Smørgrav 147*7b5038d7SDag-Erling Smørgrav status = ldns_dname_cat(hashed_sname, zone_name); 148*7b5038d7SDag-Erling Smørgrav if(status != LDNS_STATUS_OK) { 149*7b5038d7SDag-Erling Smørgrav LDNS_FREE(salt); 150*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(zone_name); 151*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(sname); 152*7b5038d7SDag-Erling Smørgrav return NULL; 153*7b5038d7SDag-Erling Smørgrav } 154*7b5038d7SDag-Erling Smørgrav 155*7b5038d7SDag-Erling Smørgrav for (nsec_i = 0; nsec_i < ldns_rr_list_rr_count(nsec3s); nsec_i++) { 156*7b5038d7SDag-Erling Smørgrav nsec = ldns_rr_list_rr(nsec3s, nsec_i); 157*7b5038d7SDag-Erling Smørgrav 158*7b5038d7SDag-Erling Smørgrav /* check values of iterations etc! */ 159*7b5038d7SDag-Erling Smørgrav 160*7b5038d7SDag-Erling Smørgrav /* exact match? */ 161*7b5038d7SDag-Erling Smørgrav if (ldns_dname_compare(ldns_rr_owner(nsec), hashed_sname) == 0) { 162*7b5038d7SDag-Erling Smørgrav exact_match_found = true; 163*7b5038d7SDag-Erling Smørgrav } else if (ldns_nsec_covers_name(nsec, hashed_sname)) { 164*7b5038d7SDag-Erling Smørgrav in_range_found = true; 165*7b5038d7SDag-Erling Smørgrav } 166*7b5038d7SDag-Erling Smørgrav 167*7b5038d7SDag-Erling Smørgrav } 168*7b5038d7SDag-Erling Smørgrav if (!exact_match_found && in_range_found) { 169*7b5038d7SDag-Erling Smørgrav flag = true; 170*7b5038d7SDag-Erling Smørgrav } else if (exact_match_found && flag) { 171*7b5038d7SDag-Erling Smørgrav result = ldns_rdf_clone(sname); 172*7b5038d7SDag-Erling Smørgrav /* RFC 5155: 8.3. 2.** "The proof is complete" */ 173*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(hashed_sname); 174*7b5038d7SDag-Erling Smørgrav goto done; 175*7b5038d7SDag-Erling Smørgrav } else if (exact_match_found && !flag) { 176*7b5038d7SDag-Erling Smørgrav /* error! */ 177*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(hashed_sname); 178*7b5038d7SDag-Erling Smørgrav goto done; 179*7b5038d7SDag-Erling Smørgrav } else { 180*7b5038d7SDag-Erling Smørgrav flag = false; 181*7b5038d7SDag-Erling Smørgrav } 182*7b5038d7SDag-Erling Smørgrav 183*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(hashed_sname); 184*7b5038d7SDag-Erling Smørgrav tmp = sname; 185*7b5038d7SDag-Erling Smørgrav sname = ldns_dname_left_chop(sname); 186*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(tmp); 187*7b5038d7SDag-Erling Smørgrav } 188*7b5038d7SDag-Erling Smørgrav 189*7b5038d7SDag-Erling Smørgrav done: 190*7b5038d7SDag-Erling Smørgrav LDNS_FREE(salt); 191*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(zone_name); 192*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(sname); 193*7b5038d7SDag-Erling Smørgrav 194*7b5038d7SDag-Erling Smørgrav return result; 195*7b5038d7SDag-Erling Smørgrav } 196*7b5038d7SDag-Erling Smørgrav 197*7b5038d7SDag-Erling Smørgrav bool 198*7b5038d7SDag-Erling Smørgrav ldns_dnssec_pkt_has_rrsigs(const ldns_pkt *pkt) 199*7b5038d7SDag-Erling Smørgrav { 200*7b5038d7SDag-Erling Smørgrav size_t i; 201*7b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_pkt_ancount(pkt); i++) { 202*7b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(ldns_rr_list_rr(ldns_pkt_answer(pkt), i)) == 203*7b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_RRSIG) { 204*7b5038d7SDag-Erling Smørgrav return true; 205*7b5038d7SDag-Erling Smørgrav } 206*7b5038d7SDag-Erling Smørgrav } 207*7b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_pkt_nscount(pkt); i++) { 208*7b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(ldns_rr_list_rr(ldns_pkt_authority(pkt), i)) == 209*7b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_RRSIG) { 210*7b5038d7SDag-Erling Smørgrav return true; 211*7b5038d7SDag-Erling Smørgrav } 212*7b5038d7SDag-Erling Smørgrav } 213*7b5038d7SDag-Erling Smørgrav return false; 214*7b5038d7SDag-Erling Smørgrav } 215*7b5038d7SDag-Erling Smørgrav 216*7b5038d7SDag-Erling Smørgrav ldns_rr_list * 217*7b5038d7SDag-Erling Smørgrav ldns_dnssec_pkt_get_rrsigs_for_name_and_type(const ldns_pkt *pkt, 218*7b5038d7SDag-Erling Smørgrav ldns_rdf *name, 219*7b5038d7SDag-Erling Smørgrav ldns_rr_type type) 220*7b5038d7SDag-Erling Smørgrav { 221*7b5038d7SDag-Erling Smørgrav uint16_t t_netorder; 222*7b5038d7SDag-Erling Smørgrav ldns_rr_list *sigs; 223*7b5038d7SDag-Erling Smørgrav ldns_rr_list *sigs_covered; 224*7b5038d7SDag-Erling Smørgrav ldns_rdf *rdf_t; 225*7b5038d7SDag-Erling Smørgrav 226*7b5038d7SDag-Erling Smørgrav sigs = ldns_pkt_rr_list_by_name_and_type(pkt, 227*7b5038d7SDag-Erling Smørgrav name, 228*7b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_RRSIG, 229*7b5038d7SDag-Erling Smørgrav LDNS_SECTION_ANY_NOQUESTION 230*7b5038d7SDag-Erling Smørgrav ); 231*7b5038d7SDag-Erling Smørgrav 232*7b5038d7SDag-Erling Smørgrav t_netorder = htons(type); /* rdf are in network order! */ 233*7b5038d7SDag-Erling Smørgrav rdf_t = ldns_rdf_new(LDNS_RDF_TYPE_TYPE, LDNS_RDF_SIZE_WORD, &t_netorder); 234*7b5038d7SDag-Erling Smørgrav sigs_covered = ldns_rr_list_subtype_by_rdf(sigs, rdf_t, 0); 235*7b5038d7SDag-Erling Smørgrav 236*7b5038d7SDag-Erling Smørgrav ldns_rdf_free(rdf_t); 237*7b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(sigs); 238*7b5038d7SDag-Erling Smørgrav 239*7b5038d7SDag-Erling Smørgrav return sigs_covered; 240*7b5038d7SDag-Erling Smørgrav 241*7b5038d7SDag-Erling Smørgrav } 242*7b5038d7SDag-Erling Smørgrav 243*7b5038d7SDag-Erling Smørgrav ldns_rr_list * 244*7b5038d7SDag-Erling Smørgrav ldns_dnssec_pkt_get_rrsigs_for_type(const ldns_pkt *pkt, ldns_rr_type type) 245*7b5038d7SDag-Erling Smørgrav { 246*7b5038d7SDag-Erling Smørgrav uint16_t t_netorder; 247*7b5038d7SDag-Erling Smørgrav ldns_rr_list *sigs; 248*7b5038d7SDag-Erling Smørgrav ldns_rr_list *sigs_covered; 249*7b5038d7SDag-Erling Smørgrav ldns_rdf *rdf_t; 250*7b5038d7SDag-Erling Smørgrav 251*7b5038d7SDag-Erling Smørgrav sigs = ldns_pkt_rr_list_by_type(pkt, 252*7b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_RRSIG, 253*7b5038d7SDag-Erling Smørgrav LDNS_SECTION_ANY_NOQUESTION 254*7b5038d7SDag-Erling Smørgrav ); 255*7b5038d7SDag-Erling Smørgrav 256*7b5038d7SDag-Erling Smørgrav t_netorder = htons(type); /* rdf are in network order! */ 257*7b5038d7SDag-Erling Smørgrav rdf_t = ldns_rdf_new(LDNS_RDF_TYPE_TYPE, 258*7b5038d7SDag-Erling Smørgrav 2, 259*7b5038d7SDag-Erling Smørgrav &t_netorder); 260*7b5038d7SDag-Erling Smørgrav sigs_covered = ldns_rr_list_subtype_by_rdf(sigs, rdf_t, 0); 261*7b5038d7SDag-Erling Smørgrav 262*7b5038d7SDag-Erling Smørgrav ldns_rdf_free(rdf_t); 263*7b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(sigs); 264*7b5038d7SDag-Erling Smørgrav 265*7b5038d7SDag-Erling Smørgrav return sigs_covered; 266*7b5038d7SDag-Erling Smørgrav 267*7b5038d7SDag-Erling Smørgrav } 268*7b5038d7SDag-Erling Smørgrav 269*7b5038d7SDag-Erling Smørgrav /* used only on the public key RR */ 270*7b5038d7SDag-Erling Smørgrav uint16_t 271*7b5038d7SDag-Erling Smørgrav ldns_calc_keytag(const ldns_rr *key) 272*7b5038d7SDag-Erling Smørgrav { 273*7b5038d7SDag-Erling Smørgrav uint16_t ac16; 274*7b5038d7SDag-Erling Smørgrav ldns_buffer *keybuf; 275*7b5038d7SDag-Erling Smørgrav size_t keysize; 276*7b5038d7SDag-Erling Smørgrav 277*7b5038d7SDag-Erling Smørgrav if (!key) { 278*7b5038d7SDag-Erling Smørgrav return 0; 279*7b5038d7SDag-Erling Smørgrav } 280*7b5038d7SDag-Erling Smørgrav 281*7b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(key) != LDNS_RR_TYPE_DNSKEY && 282*7b5038d7SDag-Erling Smørgrav ldns_rr_get_type(key) != LDNS_RR_TYPE_KEY 283*7b5038d7SDag-Erling Smørgrav ) { 284*7b5038d7SDag-Erling Smørgrav return 0; 285*7b5038d7SDag-Erling Smørgrav } 286*7b5038d7SDag-Erling Smørgrav 287*7b5038d7SDag-Erling Smørgrav /* rdata to buf - only put the rdata in a buffer */ 288*7b5038d7SDag-Erling Smørgrav keybuf = ldns_buffer_new(LDNS_MIN_BUFLEN); /* grows */ 289*7b5038d7SDag-Erling Smørgrav if (!keybuf) { 290*7b5038d7SDag-Erling Smørgrav return 0; 291*7b5038d7SDag-Erling Smørgrav } 292*7b5038d7SDag-Erling Smørgrav (void)ldns_rr_rdata2buffer_wire(keybuf, key); 293*7b5038d7SDag-Erling Smørgrav /* the current pos in the buffer is the keysize */ 294*7b5038d7SDag-Erling Smørgrav keysize= ldns_buffer_position(keybuf); 295*7b5038d7SDag-Erling Smørgrav 296*7b5038d7SDag-Erling Smørgrav ac16 = ldns_calc_keytag_raw(ldns_buffer_begin(keybuf), keysize); 297*7b5038d7SDag-Erling Smørgrav ldns_buffer_free(keybuf); 298*7b5038d7SDag-Erling Smørgrav return ac16; 299*7b5038d7SDag-Erling Smørgrav } 300*7b5038d7SDag-Erling Smørgrav 301*7b5038d7SDag-Erling Smørgrav uint16_t ldns_calc_keytag_raw(uint8_t* key, size_t keysize) 302*7b5038d7SDag-Erling Smørgrav { 303*7b5038d7SDag-Erling Smørgrav unsigned int i; 304*7b5038d7SDag-Erling Smørgrav uint32_t ac32; 305*7b5038d7SDag-Erling Smørgrav uint16_t ac16; 306*7b5038d7SDag-Erling Smørgrav 307*7b5038d7SDag-Erling Smørgrav if(keysize < 4) { 308*7b5038d7SDag-Erling Smørgrav return 0; 309*7b5038d7SDag-Erling Smørgrav } 310*7b5038d7SDag-Erling Smørgrav /* look at the algorithm field, copied from 2535bis */ 311*7b5038d7SDag-Erling Smørgrav if (key[3] == LDNS_RSAMD5) { 312*7b5038d7SDag-Erling Smørgrav ac16 = 0; 313*7b5038d7SDag-Erling Smørgrav if (keysize > 4) { 314*7b5038d7SDag-Erling Smørgrav memmove(&ac16, key + keysize - 3, 2); 315*7b5038d7SDag-Erling Smørgrav } 316*7b5038d7SDag-Erling Smørgrav ac16 = ntohs(ac16); 317*7b5038d7SDag-Erling Smørgrav return (uint16_t) ac16; 318*7b5038d7SDag-Erling Smørgrav } else { 319*7b5038d7SDag-Erling Smørgrav ac32 = 0; 320*7b5038d7SDag-Erling Smørgrav for (i = 0; (size_t)i < keysize; ++i) { 321*7b5038d7SDag-Erling Smørgrav ac32 += (i & 1) ? key[i] : key[i] << 8; 322*7b5038d7SDag-Erling Smørgrav } 323*7b5038d7SDag-Erling Smørgrav ac32 += (ac32 >> 16) & 0xFFFF; 324*7b5038d7SDag-Erling Smørgrav return (uint16_t) (ac32 & 0xFFFF); 325*7b5038d7SDag-Erling Smørgrav } 326*7b5038d7SDag-Erling Smørgrav } 327*7b5038d7SDag-Erling Smørgrav 328*7b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 329*7b5038d7SDag-Erling Smørgrav DSA * 330*7b5038d7SDag-Erling Smørgrav ldns_key_buf2dsa(ldns_buffer *key) 331*7b5038d7SDag-Erling Smørgrav { 332*7b5038d7SDag-Erling Smørgrav return ldns_key_buf2dsa_raw((unsigned char*)ldns_buffer_begin(key), 333*7b5038d7SDag-Erling Smørgrav ldns_buffer_position(key)); 334*7b5038d7SDag-Erling Smørgrav } 335*7b5038d7SDag-Erling Smørgrav 336*7b5038d7SDag-Erling Smørgrav DSA * 337*7b5038d7SDag-Erling Smørgrav ldns_key_buf2dsa_raw(unsigned char* key, size_t len) 338*7b5038d7SDag-Erling Smørgrav { 339*7b5038d7SDag-Erling Smørgrav uint8_t T; 340*7b5038d7SDag-Erling Smørgrav uint16_t length; 341*7b5038d7SDag-Erling Smørgrav uint16_t offset; 342*7b5038d7SDag-Erling Smørgrav DSA *dsa; 343*7b5038d7SDag-Erling Smørgrav BIGNUM *Q; BIGNUM *P; 344*7b5038d7SDag-Erling Smørgrav BIGNUM *G; BIGNUM *Y; 345*7b5038d7SDag-Erling Smørgrav 346*7b5038d7SDag-Erling Smørgrav if(len == 0) 347*7b5038d7SDag-Erling Smørgrav return NULL; 348*7b5038d7SDag-Erling Smørgrav T = (uint8_t)key[0]; 349*7b5038d7SDag-Erling Smørgrav length = (64 + T * 8); 350*7b5038d7SDag-Erling Smørgrav offset = 1; 351*7b5038d7SDag-Erling Smørgrav 352*7b5038d7SDag-Erling Smørgrav if (T > 8) { 353*7b5038d7SDag-Erling Smørgrav return NULL; 354*7b5038d7SDag-Erling Smørgrav } 355*7b5038d7SDag-Erling Smørgrav if(len < (size_t)1 + SHA_DIGEST_LENGTH + 3*length) 356*7b5038d7SDag-Erling Smørgrav return NULL; 357*7b5038d7SDag-Erling Smørgrav 358*7b5038d7SDag-Erling Smørgrav Q = BN_bin2bn(key+offset, SHA_DIGEST_LENGTH, NULL); 359*7b5038d7SDag-Erling Smørgrav offset += SHA_DIGEST_LENGTH; 360*7b5038d7SDag-Erling Smørgrav 361*7b5038d7SDag-Erling Smørgrav P = BN_bin2bn(key+offset, (int)length, NULL); 362*7b5038d7SDag-Erling Smørgrav offset += length; 363*7b5038d7SDag-Erling Smørgrav 364*7b5038d7SDag-Erling Smørgrav G = BN_bin2bn(key+offset, (int)length, NULL); 365*7b5038d7SDag-Erling Smørgrav offset += length; 366*7b5038d7SDag-Erling Smørgrav 367*7b5038d7SDag-Erling Smørgrav Y = BN_bin2bn(key+offset, (int)length, NULL); 368*7b5038d7SDag-Erling Smørgrav offset += length; 369*7b5038d7SDag-Erling Smørgrav 370*7b5038d7SDag-Erling Smørgrav /* create the key and set its properties */ 371*7b5038d7SDag-Erling Smørgrav if(!Q || !P || !G || !Y || !(dsa = DSA_new())) { 372*7b5038d7SDag-Erling Smørgrav BN_free(Q); 373*7b5038d7SDag-Erling Smørgrav BN_free(P); 374*7b5038d7SDag-Erling Smørgrav BN_free(G); 375*7b5038d7SDag-Erling Smørgrav BN_free(Y); 376*7b5038d7SDag-Erling Smørgrav return NULL; 377*7b5038d7SDag-Erling Smørgrav } 378*7b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S 379*7b5038d7SDag-Erling Smørgrav dsa->p = P; 380*7b5038d7SDag-Erling Smørgrav dsa->q = Q; 381*7b5038d7SDag-Erling Smørgrav dsa->g = G; 382*7b5038d7SDag-Erling Smørgrav dsa->pub_key = Y; 383*7b5038d7SDag-Erling Smørgrav #endif /* splint */ 384*7b5038d7SDag-Erling Smørgrav 385*7b5038d7SDag-Erling Smørgrav return dsa; 386*7b5038d7SDag-Erling Smørgrav } 387*7b5038d7SDag-Erling Smørgrav 388*7b5038d7SDag-Erling Smørgrav RSA * 389*7b5038d7SDag-Erling Smørgrav ldns_key_buf2rsa(ldns_buffer *key) 390*7b5038d7SDag-Erling Smørgrav { 391*7b5038d7SDag-Erling Smørgrav return ldns_key_buf2rsa_raw((unsigned char*)ldns_buffer_begin(key), 392*7b5038d7SDag-Erling Smørgrav ldns_buffer_position(key)); 393*7b5038d7SDag-Erling Smørgrav } 394*7b5038d7SDag-Erling Smørgrav 395*7b5038d7SDag-Erling Smørgrav RSA * 396*7b5038d7SDag-Erling Smørgrav ldns_key_buf2rsa_raw(unsigned char* key, size_t len) 397*7b5038d7SDag-Erling Smørgrav { 398*7b5038d7SDag-Erling Smørgrav uint16_t offset; 399*7b5038d7SDag-Erling Smørgrav uint16_t exp; 400*7b5038d7SDag-Erling Smørgrav uint16_t int16; 401*7b5038d7SDag-Erling Smørgrav RSA *rsa; 402*7b5038d7SDag-Erling Smørgrav BIGNUM *modulus; 403*7b5038d7SDag-Erling Smørgrav BIGNUM *exponent; 404*7b5038d7SDag-Erling Smørgrav 405*7b5038d7SDag-Erling Smørgrav if (len == 0) 406*7b5038d7SDag-Erling Smørgrav return NULL; 407*7b5038d7SDag-Erling Smørgrav if (key[0] == 0) { 408*7b5038d7SDag-Erling Smørgrav if(len < 3) 409*7b5038d7SDag-Erling Smørgrav return NULL; 410*7b5038d7SDag-Erling Smørgrav /* need some smart comment here XXX*/ 411*7b5038d7SDag-Erling Smørgrav /* the exponent is too large so it's places 412*7b5038d7SDag-Erling Smørgrav * futher...???? */ 413*7b5038d7SDag-Erling Smørgrav memmove(&int16, key+1, 2); 414*7b5038d7SDag-Erling Smørgrav exp = ntohs(int16); 415*7b5038d7SDag-Erling Smørgrav offset = 3; 416*7b5038d7SDag-Erling Smørgrav } else { 417*7b5038d7SDag-Erling Smørgrav exp = key[0]; 418*7b5038d7SDag-Erling Smørgrav offset = 1; 419*7b5038d7SDag-Erling Smørgrav } 420*7b5038d7SDag-Erling Smørgrav 421*7b5038d7SDag-Erling Smørgrav /* key length at least one */ 422*7b5038d7SDag-Erling Smørgrav if(len < (size_t)offset + exp + 1) 423*7b5038d7SDag-Erling Smørgrav return NULL; 424*7b5038d7SDag-Erling Smørgrav 425*7b5038d7SDag-Erling Smørgrav /* Exponent */ 426*7b5038d7SDag-Erling Smørgrav exponent = BN_new(); 427*7b5038d7SDag-Erling Smørgrav if(!exponent) return NULL; 428*7b5038d7SDag-Erling Smørgrav (void) BN_bin2bn(key+offset, (int)exp, exponent); 429*7b5038d7SDag-Erling Smørgrav offset += exp; 430*7b5038d7SDag-Erling Smørgrav 431*7b5038d7SDag-Erling Smørgrav /* Modulus */ 432*7b5038d7SDag-Erling Smørgrav modulus = BN_new(); 433*7b5038d7SDag-Erling Smørgrav if(!modulus) { 434*7b5038d7SDag-Erling Smørgrav BN_free(exponent); 435*7b5038d7SDag-Erling Smørgrav return NULL; 436*7b5038d7SDag-Erling Smørgrav } 437*7b5038d7SDag-Erling Smørgrav /* length of the buffer must match the key length! */ 438*7b5038d7SDag-Erling Smørgrav (void) BN_bin2bn(key+offset, (int)(len - offset), modulus); 439*7b5038d7SDag-Erling Smørgrav 440*7b5038d7SDag-Erling Smørgrav rsa = RSA_new(); 441*7b5038d7SDag-Erling Smørgrav if(!rsa) { 442*7b5038d7SDag-Erling Smørgrav BN_free(exponent); 443*7b5038d7SDag-Erling Smørgrav BN_free(modulus); 444*7b5038d7SDag-Erling Smørgrav return NULL; 445*7b5038d7SDag-Erling Smørgrav } 446*7b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S 447*7b5038d7SDag-Erling Smørgrav rsa->n = modulus; 448*7b5038d7SDag-Erling Smørgrav rsa->e = exponent; 449*7b5038d7SDag-Erling Smørgrav #endif /* splint */ 450*7b5038d7SDag-Erling Smørgrav 451*7b5038d7SDag-Erling Smørgrav return rsa; 452*7b5038d7SDag-Erling Smørgrav } 453*7b5038d7SDag-Erling Smørgrav 454*7b5038d7SDag-Erling Smørgrav int 455*7b5038d7SDag-Erling Smørgrav ldns_digest_evp(unsigned char* data, unsigned int len, unsigned char* dest, 456*7b5038d7SDag-Erling Smørgrav const EVP_MD* md) 457*7b5038d7SDag-Erling Smørgrav { 458*7b5038d7SDag-Erling Smørgrav EVP_MD_CTX* ctx; 459*7b5038d7SDag-Erling Smørgrav ctx = EVP_MD_CTX_create(); 460*7b5038d7SDag-Erling Smørgrav if(!ctx) 461*7b5038d7SDag-Erling Smørgrav return false; 462*7b5038d7SDag-Erling Smørgrav if(!EVP_DigestInit_ex(ctx, md, NULL) || 463*7b5038d7SDag-Erling Smørgrav !EVP_DigestUpdate(ctx, data, len) || 464*7b5038d7SDag-Erling Smørgrav !EVP_DigestFinal_ex(ctx, dest, NULL)) { 465*7b5038d7SDag-Erling Smørgrav EVP_MD_CTX_destroy(ctx); 466*7b5038d7SDag-Erling Smørgrav return false; 467*7b5038d7SDag-Erling Smørgrav } 468*7b5038d7SDag-Erling Smørgrav EVP_MD_CTX_destroy(ctx); 469*7b5038d7SDag-Erling Smørgrav return true; 470*7b5038d7SDag-Erling Smørgrav } 471*7b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 472*7b5038d7SDag-Erling Smørgrav 473*7b5038d7SDag-Erling Smørgrav ldns_rr * 474*7b5038d7SDag-Erling Smørgrav ldns_key_rr2ds(const ldns_rr *key, ldns_hash h) 475*7b5038d7SDag-Erling Smørgrav { 476*7b5038d7SDag-Erling Smørgrav ldns_rdf *tmp; 477*7b5038d7SDag-Erling Smørgrav ldns_rr *ds; 478*7b5038d7SDag-Erling Smørgrav uint16_t keytag; 479*7b5038d7SDag-Erling Smørgrav uint8_t sha1hash; 480*7b5038d7SDag-Erling Smørgrav uint8_t *digest; 481*7b5038d7SDag-Erling Smørgrav ldns_buffer *data_buf; 482*7b5038d7SDag-Erling Smørgrav #ifdef USE_GOST 483*7b5038d7SDag-Erling Smørgrav const EVP_MD* md = NULL; 484*7b5038d7SDag-Erling Smørgrav #endif 485*7b5038d7SDag-Erling Smørgrav 486*7b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(key) != LDNS_RR_TYPE_DNSKEY) { 487*7b5038d7SDag-Erling Smørgrav return NULL; 488*7b5038d7SDag-Erling Smørgrav } 489*7b5038d7SDag-Erling Smørgrav 490*7b5038d7SDag-Erling Smørgrav ds = ldns_rr_new(); 491*7b5038d7SDag-Erling Smørgrav if (!ds) { 492*7b5038d7SDag-Erling Smørgrav return NULL; 493*7b5038d7SDag-Erling Smørgrav } 494*7b5038d7SDag-Erling Smørgrav ldns_rr_set_type(ds, LDNS_RR_TYPE_DS); 495*7b5038d7SDag-Erling Smørgrav ldns_rr_set_owner(ds, ldns_rdf_clone( 496*7b5038d7SDag-Erling Smørgrav ldns_rr_owner(key))); 497*7b5038d7SDag-Erling Smørgrav ldns_rr_set_ttl(ds, ldns_rr_ttl(key)); 498*7b5038d7SDag-Erling Smørgrav ldns_rr_set_class(ds, ldns_rr_get_class(key)); 499*7b5038d7SDag-Erling Smørgrav 500*7b5038d7SDag-Erling Smørgrav switch(h) { 501*7b5038d7SDag-Erling Smørgrav default: 502*7b5038d7SDag-Erling Smørgrav case LDNS_SHA1: 503*7b5038d7SDag-Erling Smørgrav digest = LDNS_XMALLOC(uint8_t, LDNS_SHA1_DIGEST_LENGTH); 504*7b5038d7SDag-Erling Smørgrav if (!digest) { 505*7b5038d7SDag-Erling Smørgrav ldns_rr_free(ds); 506*7b5038d7SDag-Erling Smørgrav return NULL; 507*7b5038d7SDag-Erling Smørgrav } 508*7b5038d7SDag-Erling Smørgrav break; 509*7b5038d7SDag-Erling Smørgrav case LDNS_SHA256: 510*7b5038d7SDag-Erling Smørgrav digest = LDNS_XMALLOC(uint8_t, LDNS_SHA256_DIGEST_LENGTH); 511*7b5038d7SDag-Erling Smørgrav if (!digest) { 512*7b5038d7SDag-Erling Smørgrav ldns_rr_free(ds); 513*7b5038d7SDag-Erling Smørgrav return NULL; 514*7b5038d7SDag-Erling Smørgrav } 515*7b5038d7SDag-Erling Smørgrav break; 516*7b5038d7SDag-Erling Smørgrav case LDNS_HASH_GOST: 517*7b5038d7SDag-Erling Smørgrav #ifdef USE_GOST 518*7b5038d7SDag-Erling Smørgrav (void)ldns_key_EVP_load_gost_id(); 519*7b5038d7SDag-Erling Smørgrav md = EVP_get_digestbyname("md_gost94"); 520*7b5038d7SDag-Erling Smørgrav if(!md) { 521*7b5038d7SDag-Erling Smørgrav ldns_rr_free(ds); 522*7b5038d7SDag-Erling Smørgrav return NULL; 523*7b5038d7SDag-Erling Smørgrav } 524*7b5038d7SDag-Erling Smørgrav digest = LDNS_XMALLOC(uint8_t, EVP_MD_size(md)); 525*7b5038d7SDag-Erling Smørgrav if (!digest) { 526*7b5038d7SDag-Erling Smørgrav ldns_rr_free(ds); 527*7b5038d7SDag-Erling Smørgrav return NULL; 528*7b5038d7SDag-Erling Smørgrav } 529*7b5038d7SDag-Erling Smørgrav break; 530*7b5038d7SDag-Erling Smørgrav #else 531*7b5038d7SDag-Erling Smørgrav /* not implemented */ 532*7b5038d7SDag-Erling Smørgrav ldns_rr_free(ds); 533*7b5038d7SDag-Erling Smørgrav return NULL; 534*7b5038d7SDag-Erling Smørgrav #endif 535*7b5038d7SDag-Erling Smørgrav case LDNS_SHA384: 536*7b5038d7SDag-Erling Smørgrav #ifdef USE_ECDSA 537*7b5038d7SDag-Erling Smørgrav digest = LDNS_XMALLOC(uint8_t, SHA384_DIGEST_LENGTH); 538*7b5038d7SDag-Erling Smørgrav if (!digest) { 539*7b5038d7SDag-Erling Smørgrav ldns_rr_free(ds); 540*7b5038d7SDag-Erling Smørgrav return NULL; 541*7b5038d7SDag-Erling Smørgrav } 542*7b5038d7SDag-Erling Smørgrav break; 543*7b5038d7SDag-Erling Smørgrav #else 544*7b5038d7SDag-Erling Smørgrav /* not implemented */ 545*7b5038d7SDag-Erling Smørgrav ldns_rr_free(ds); 546*7b5038d7SDag-Erling Smørgrav return NULL; 547*7b5038d7SDag-Erling Smørgrav #endif 548*7b5038d7SDag-Erling Smørgrav } 549*7b5038d7SDag-Erling Smørgrav 550*7b5038d7SDag-Erling Smørgrav data_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN); 551*7b5038d7SDag-Erling Smørgrav if (!data_buf) { 552*7b5038d7SDag-Erling Smørgrav LDNS_FREE(digest); 553*7b5038d7SDag-Erling Smørgrav ldns_rr_free(ds); 554*7b5038d7SDag-Erling Smørgrav return NULL; 555*7b5038d7SDag-Erling Smørgrav } 556*7b5038d7SDag-Erling Smørgrav 557*7b5038d7SDag-Erling Smørgrav /* keytag */ 558*7b5038d7SDag-Erling Smørgrav keytag = htons(ldns_calc_keytag((ldns_rr*)key)); 559*7b5038d7SDag-Erling Smørgrav tmp = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_INT16, 560*7b5038d7SDag-Erling Smørgrav sizeof(uint16_t), 561*7b5038d7SDag-Erling Smørgrav &keytag); 562*7b5038d7SDag-Erling Smørgrav ldns_rr_push_rdf(ds, tmp); 563*7b5038d7SDag-Erling Smørgrav 564*7b5038d7SDag-Erling Smørgrav /* copy the algorithm field */ 565*7b5038d7SDag-Erling Smørgrav if ((tmp = ldns_rr_rdf(key, 2)) == NULL) { 566*7b5038d7SDag-Erling Smørgrav LDNS_FREE(digest); 567*7b5038d7SDag-Erling Smørgrav ldns_buffer_free(data_buf); 568*7b5038d7SDag-Erling Smørgrav ldns_rr_free(ds); 569*7b5038d7SDag-Erling Smørgrav return NULL; 570*7b5038d7SDag-Erling Smørgrav } else { 571*7b5038d7SDag-Erling Smørgrav ldns_rr_push_rdf(ds, ldns_rdf_clone( tmp )); 572*7b5038d7SDag-Erling Smørgrav } 573*7b5038d7SDag-Erling Smørgrav 574*7b5038d7SDag-Erling Smørgrav /* digest hash type */ 575*7b5038d7SDag-Erling Smørgrav sha1hash = (uint8_t)h; 576*7b5038d7SDag-Erling Smørgrav tmp = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_INT8, 577*7b5038d7SDag-Erling Smørgrav sizeof(uint8_t), 578*7b5038d7SDag-Erling Smørgrav &sha1hash); 579*7b5038d7SDag-Erling Smørgrav ldns_rr_push_rdf(ds, tmp); 580*7b5038d7SDag-Erling Smørgrav 581*7b5038d7SDag-Erling Smørgrav /* digest */ 582*7b5038d7SDag-Erling Smørgrav /* owner name */ 583*7b5038d7SDag-Erling Smørgrav tmp = ldns_rdf_clone(ldns_rr_owner(key)); 584*7b5038d7SDag-Erling Smørgrav ldns_dname2canonical(tmp); 585*7b5038d7SDag-Erling Smørgrav if (ldns_rdf2buffer_wire(data_buf, tmp) != LDNS_STATUS_OK) { 586*7b5038d7SDag-Erling Smørgrav LDNS_FREE(digest); 587*7b5038d7SDag-Erling Smørgrav ldns_buffer_free(data_buf); 588*7b5038d7SDag-Erling Smørgrav ldns_rr_free(ds); 589*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(tmp); 590*7b5038d7SDag-Erling Smørgrav return NULL; 591*7b5038d7SDag-Erling Smørgrav } 592*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(tmp); 593*7b5038d7SDag-Erling Smørgrav 594*7b5038d7SDag-Erling Smørgrav /* all the rdata's */ 595*7b5038d7SDag-Erling Smørgrav if (ldns_rr_rdata2buffer_wire(data_buf, 596*7b5038d7SDag-Erling Smørgrav (ldns_rr*)key) != LDNS_STATUS_OK) { 597*7b5038d7SDag-Erling Smørgrav LDNS_FREE(digest); 598*7b5038d7SDag-Erling Smørgrav ldns_buffer_free(data_buf); 599*7b5038d7SDag-Erling Smørgrav ldns_rr_free(ds); 600*7b5038d7SDag-Erling Smørgrav return NULL; 601*7b5038d7SDag-Erling Smørgrav } 602*7b5038d7SDag-Erling Smørgrav switch(h) { 603*7b5038d7SDag-Erling Smørgrav case LDNS_SHA1: 604*7b5038d7SDag-Erling Smørgrav (void) ldns_sha1((unsigned char *) ldns_buffer_begin(data_buf), 605*7b5038d7SDag-Erling Smørgrav (unsigned int) ldns_buffer_position(data_buf), 606*7b5038d7SDag-Erling Smørgrav (unsigned char *) digest); 607*7b5038d7SDag-Erling Smørgrav 608*7b5038d7SDag-Erling Smørgrav tmp = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_HEX, 609*7b5038d7SDag-Erling Smørgrav LDNS_SHA1_DIGEST_LENGTH, 610*7b5038d7SDag-Erling Smørgrav digest); 611*7b5038d7SDag-Erling Smørgrav ldns_rr_push_rdf(ds, tmp); 612*7b5038d7SDag-Erling Smørgrav 613*7b5038d7SDag-Erling Smørgrav break; 614*7b5038d7SDag-Erling Smørgrav case LDNS_SHA256: 615*7b5038d7SDag-Erling Smørgrav (void) ldns_sha256((unsigned char *) ldns_buffer_begin(data_buf), 616*7b5038d7SDag-Erling Smørgrav (unsigned int) ldns_buffer_position(data_buf), 617*7b5038d7SDag-Erling Smørgrav (unsigned char *) digest); 618*7b5038d7SDag-Erling Smørgrav tmp = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_HEX, 619*7b5038d7SDag-Erling Smørgrav LDNS_SHA256_DIGEST_LENGTH, 620*7b5038d7SDag-Erling Smørgrav digest); 621*7b5038d7SDag-Erling Smørgrav ldns_rr_push_rdf(ds, tmp); 622*7b5038d7SDag-Erling Smørgrav break; 623*7b5038d7SDag-Erling Smørgrav case LDNS_HASH_GOST: 624*7b5038d7SDag-Erling Smørgrav #ifdef USE_GOST 625*7b5038d7SDag-Erling Smørgrav if(!ldns_digest_evp((unsigned char *) ldns_buffer_begin(data_buf), 626*7b5038d7SDag-Erling Smørgrav (unsigned int) ldns_buffer_position(data_buf), 627*7b5038d7SDag-Erling Smørgrav (unsigned char *) digest, md)) { 628*7b5038d7SDag-Erling Smørgrav LDNS_FREE(digest); 629*7b5038d7SDag-Erling Smørgrav ldns_buffer_free(data_buf); 630*7b5038d7SDag-Erling Smørgrav ldns_rr_free(ds); 631*7b5038d7SDag-Erling Smørgrav return NULL; 632*7b5038d7SDag-Erling Smørgrav } 633*7b5038d7SDag-Erling Smørgrav tmp = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_HEX, 634*7b5038d7SDag-Erling Smørgrav (size_t)EVP_MD_size(md), 635*7b5038d7SDag-Erling Smørgrav digest); 636*7b5038d7SDag-Erling Smørgrav ldns_rr_push_rdf(ds, tmp); 637*7b5038d7SDag-Erling Smørgrav #endif 638*7b5038d7SDag-Erling Smørgrav break; 639*7b5038d7SDag-Erling Smørgrav case LDNS_SHA384: 640*7b5038d7SDag-Erling Smørgrav #ifdef USE_ECDSA 641*7b5038d7SDag-Erling Smørgrav (void) SHA384((unsigned char *) ldns_buffer_begin(data_buf), 642*7b5038d7SDag-Erling Smørgrav (unsigned int) ldns_buffer_position(data_buf), 643*7b5038d7SDag-Erling Smørgrav (unsigned char *) digest); 644*7b5038d7SDag-Erling Smørgrav tmp = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_HEX, 645*7b5038d7SDag-Erling Smørgrav SHA384_DIGEST_LENGTH, 646*7b5038d7SDag-Erling Smørgrav digest); 647*7b5038d7SDag-Erling Smørgrav ldns_rr_push_rdf(ds, tmp); 648*7b5038d7SDag-Erling Smørgrav #endif 649*7b5038d7SDag-Erling Smørgrav break; 650*7b5038d7SDag-Erling Smørgrav } 651*7b5038d7SDag-Erling Smørgrav 652*7b5038d7SDag-Erling Smørgrav LDNS_FREE(digest); 653*7b5038d7SDag-Erling Smørgrav ldns_buffer_free(data_buf); 654*7b5038d7SDag-Erling Smørgrav return ds; 655*7b5038d7SDag-Erling Smørgrav } 656*7b5038d7SDag-Erling Smørgrav 657*7b5038d7SDag-Erling Smørgrav ldns_rdf * 658*7b5038d7SDag-Erling Smørgrav ldns_dnssec_create_nsec_bitmap(ldns_rr_type rr_type_list[], 659*7b5038d7SDag-Erling Smørgrav size_t size, 660*7b5038d7SDag-Erling Smørgrav ldns_rr_type nsec_type) 661*7b5038d7SDag-Erling Smørgrav { 662*7b5038d7SDag-Erling Smørgrav size_t i; 663*7b5038d7SDag-Erling Smørgrav uint8_t *bitmap; 664*7b5038d7SDag-Erling Smørgrav uint16_t bm_len = 0; 665*7b5038d7SDag-Erling Smørgrav uint16_t i_type; 666*7b5038d7SDag-Erling Smørgrav ldns_rdf *bitmap_rdf; 667*7b5038d7SDag-Erling Smørgrav 668*7b5038d7SDag-Erling Smørgrav uint8_t *data = NULL; 669*7b5038d7SDag-Erling Smørgrav uint8_t cur_data[32]; 670*7b5038d7SDag-Erling Smørgrav uint8_t cur_window = 0; 671*7b5038d7SDag-Erling Smørgrav uint8_t cur_window_max = 0; 672*7b5038d7SDag-Erling Smørgrav uint16_t cur_data_size = 0; 673*7b5038d7SDag-Erling Smørgrav 674*7b5038d7SDag-Erling Smørgrav if (nsec_type != LDNS_RR_TYPE_NSEC && 675*7b5038d7SDag-Erling Smørgrav nsec_type != LDNS_RR_TYPE_NSEC3) { 676*7b5038d7SDag-Erling Smørgrav return NULL; 677*7b5038d7SDag-Erling Smørgrav } 678*7b5038d7SDag-Erling Smørgrav 679*7b5038d7SDag-Erling Smørgrav i_type = 0; 680*7b5038d7SDag-Erling Smørgrav for (i = 0; i < size; i++) { 681*7b5038d7SDag-Erling Smørgrav if (i_type < rr_type_list[i]) 682*7b5038d7SDag-Erling Smørgrav i_type = rr_type_list[i]; 683*7b5038d7SDag-Erling Smørgrav } 684*7b5038d7SDag-Erling Smørgrav if (i_type < nsec_type) { 685*7b5038d7SDag-Erling Smørgrav i_type = nsec_type; 686*7b5038d7SDag-Erling Smørgrav } 687*7b5038d7SDag-Erling Smørgrav 688*7b5038d7SDag-Erling Smørgrav bm_len = i_type / 8 + 2; 689*7b5038d7SDag-Erling Smørgrav bitmap = LDNS_XMALLOC(uint8_t, bm_len); 690*7b5038d7SDag-Erling Smørgrav if(!bitmap) return NULL; 691*7b5038d7SDag-Erling Smørgrav for (i = 0; i < bm_len; i++) { 692*7b5038d7SDag-Erling Smørgrav bitmap[i] = 0; 693*7b5038d7SDag-Erling Smørgrav } 694*7b5038d7SDag-Erling Smørgrav 695*7b5038d7SDag-Erling Smørgrav for (i = 0; i < size; i++) { 696*7b5038d7SDag-Erling Smørgrav i_type = rr_type_list[i]; 697*7b5038d7SDag-Erling Smørgrav ldns_set_bit(bitmap + (int) i_type / 8, 698*7b5038d7SDag-Erling Smørgrav (int) (7 - (i_type % 8)), 699*7b5038d7SDag-Erling Smørgrav true); 700*7b5038d7SDag-Erling Smørgrav } 701*7b5038d7SDag-Erling Smørgrav 702*7b5038d7SDag-Erling Smørgrav /* fold it into windows TODO: can this be done directly? */ 703*7b5038d7SDag-Erling Smørgrav memset(cur_data, 0, 32); 704*7b5038d7SDag-Erling Smørgrav for (i = 0; i < bm_len; i++) { 705*7b5038d7SDag-Erling Smørgrav if (i / 32 > cur_window) { 706*7b5038d7SDag-Erling Smørgrav /* check, copy, new */ 707*7b5038d7SDag-Erling Smørgrav if (cur_window_max > 0) { 708*7b5038d7SDag-Erling Smørgrav /* this window has stuff, add it */ 709*7b5038d7SDag-Erling Smørgrav data = LDNS_XREALLOC(data, 710*7b5038d7SDag-Erling Smørgrav uint8_t, 711*7b5038d7SDag-Erling Smørgrav cur_data_size + cur_window_max + 3); 712*7b5038d7SDag-Erling Smørgrav if(!data) { 713*7b5038d7SDag-Erling Smørgrav LDNS_FREE(bitmap); 714*7b5038d7SDag-Erling Smørgrav return NULL; 715*7b5038d7SDag-Erling Smørgrav } 716*7b5038d7SDag-Erling Smørgrav data[cur_data_size] = cur_window; 717*7b5038d7SDag-Erling Smørgrav data[cur_data_size + 1] = cur_window_max + 1; 718*7b5038d7SDag-Erling Smørgrav memcpy(data + cur_data_size + 2, 719*7b5038d7SDag-Erling Smørgrav cur_data, 720*7b5038d7SDag-Erling Smørgrav cur_window_max+1); 721*7b5038d7SDag-Erling Smørgrav cur_data_size += cur_window_max + 3; 722*7b5038d7SDag-Erling Smørgrav } 723*7b5038d7SDag-Erling Smørgrav cur_window++; 724*7b5038d7SDag-Erling Smørgrav cur_window_max = 0; 725*7b5038d7SDag-Erling Smørgrav memset(cur_data, 0, 32); 726*7b5038d7SDag-Erling Smørgrav } 727*7b5038d7SDag-Erling Smørgrav cur_data[i%32] = bitmap[i]; 728*7b5038d7SDag-Erling Smørgrav if (bitmap[i] > 0) { 729*7b5038d7SDag-Erling Smørgrav cur_window_max = i%32; 730*7b5038d7SDag-Erling Smørgrav } 731*7b5038d7SDag-Erling Smørgrav } 732*7b5038d7SDag-Erling Smørgrav if (cur_window_max > 0 || cur_data[0] != 0) { 733*7b5038d7SDag-Erling Smørgrav /* this window has stuff, add it */ 734*7b5038d7SDag-Erling Smørgrav data = LDNS_XREALLOC(data, 735*7b5038d7SDag-Erling Smørgrav uint8_t, 736*7b5038d7SDag-Erling Smørgrav cur_data_size + cur_window_max + 3); 737*7b5038d7SDag-Erling Smørgrav if(!data) { 738*7b5038d7SDag-Erling Smørgrav LDNS_FREE(bitmap); 739*7b5038d7SDag-Erling Smørgrav return NULL; 740*7b5038d7SDag-Erling Smørgrav } 741*7b5038d7SDag-Erling Smørgrav data[cur_data_size] = cur_window; 742*7b5038d7SDag-Erling Smørgrav data[cur_data_size + 1] = cur_window_max + 1; 743*7b5038d7SDag-Erling Smørgrav memcpy(data + cur_data_size + 2, cur_data, cur_window_max+1); 744*7b5038d7SDag-Erling Smørgrav cur_data_size += cur_window_max + 3; 745*7b5038d7SDag-Erling Smørgrav } 746*7b5038d7SDag-Erling Smørgrav 747*7b5038d7SDag-Erling Smørgrav bitmap_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_NSEC, 748*7b5038d7SDag-Erling Smørgrav cur_data_size, 749*7b5038d7SDag-Erling Smørgrav data); 750*7b5038d7SDag-Erling Smørgrav 751*7b5038d7SDag-Erling Smørgrav LDNS_FREE(bitmap); 752*7b5038d7SDag-Erling Smørgrav LDNS_FREE(data); 753*7b5038d7SDag-Erling Smørgrav 754*7b5038d7SDag-Erling Smørgrav return bitmap_rdf; 755*7b5038d7SDag-Erling Smørgrav } 756*7b5038d7SDag-Erling Smørgrav 757*7b5038d7SDag-Erling Smørgrav int 758*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets_contains_type(ldns_dnssec_rrsets *rrsets, 759*7b5038d7SDag-Erling Smørgrav ldns_rr_type type) 760*7b5038d7SDag-Erling Smørgrav { 761*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets *cur_rrset = rrsets; 762*7b5038d7SDag-Erling Smørgrav while (cur_rrset) { 763*7b5038d7SDag-Erling Smørgrav if (cur_rrset->type == type) { 764*7b5038d7SDag-Erling Smørgrav return 1; 765*7b5038d7SDag-Erling Smørgrav } 766*7b5038d7SDag-Erling Smørgrav cur_rrset = cur_rrset->next; 767*7b5038d7SDag-Erling Smørgrav } 768*7b5038d7SDag-Erling Smørgrav return 0; 769*7b5038d7SDag-Erling Smørgrav } 770*7b5038d7SDag-Erling Smørgrav 771*7b5038d7SDag-Erling Smørgrav ldns_rr * 772*7b5038d7SDag-Erling Smørgrav ldns_dnssec_create_nsec(ldns_dnssec_name *from, 773*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name *to, 774*7b5038d7SDag-Erling Smørgrav ldns_rr_type nsec_type) 775*7b5038d7SDag-Erling Smørgrav { 776*7b5038d7SDag-Erling Smørgrav ldns_rr *nsec_rr; 777*7b5038d7SDag-Erling Smørgrav ldns_rr_type types[65536]; 778*7b5038d7SDag-Erling Smørgrav size_t type_count = 0; 779*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets *cur_rrsets; 780*7b5038d7SDag-Erling Smørgrav int on_delegation_point; 781*7b5038d7SDag-Erling Smørgrav 782*7b5038d7SDag-Erling Smørgrav if (!from || !to || (nsec_type != LDNS_RR_TYPE_NSEC)) { 783*7b5038d7SDag-Erling Smørgrav return NULL; 784*7b5038d7SDag-Erling Smørgrav } 785*7b5038d7SDag-Erling Smørgrav 786*7b5038d7SDag-Erling Smørgrav nsec_rr = ldns_rr_new(); 787*7b5038d7SDag-Erling Smørgrav ldns_rr_set_type(nsec_rr, nsec_type); 788*7b5038d7SDag-Erling Smørgrav ldns_rr_set_owner(nsec_rr, ldns_rdf_clone(ldns_dnssec_name_name(from))); 789*7b5038d7SDag-Erling Smørgrav ldns_rr_push_rdf(nsec_rr, ldns_rdf_clone(ldns_dnssec_name_name(to))); 790*7b5038d7SDag-Erling Smørgrav 791*7b5038d7SDag-Erling Smørgrav on_delegation_point = ldns_dnssec_rrsets_contains_type( 792*7b5038d7SDag-Erling Smørgrav from->rrsets, LDNS_RR_TYPE_NS) 793*7b5038d7SDag-Erling Smørgrav && !ldns_dnssec_rrsets_contains_type( 794*7b5038d7SDag-Erling Smørgrav from->rrsets, LDNS_RR_TYPE_SOA); 795*7b5038d7SDag-Erling Smørgrav 796*7b5038d7SDag-Erling Smørgrav cur_rrsets = from->rrsets; 797*7b5038d7SDag-Erling Smørgrav while (cur_rrsets) { 798*7b5038d7SDag-Erling Smørgrav /* Do not include non-authoritative rrsets on the delegation point 799*7b5038d7SDag-Erling Smørgrav * in the type bitmap */ 800*7b5038d7SDag-Erling Smørgrav if ((on_delegation_point && ( 801*7b5038d7SDag-Erling Smørgrav cur_rrsets->type == LDNS_RR_TYPE_NS 802*7b5038d7SDag-Erling Smørgrav || cur_rrsets->type == LDNS_RR_TYPE_DS)) 803*7b5038d7SDag-Erling Smørgrav || (!on_delegation_point && 804*7b5038d7SDag-Erling Smørgrav cur_rrsets->type != LDNS_RR_TYPE_RRSIG 805*7b5038d7SDag-Erling Smørgrav && cur_rrsets->type != LDNS_RR_TYPE_NSEC)) { 806*7b5038d7SDag-Erling Smørgrav 807*7b5038d7SDag-Erling Smørgrav types[type_count] = cur_rrsets->type; 808*7b5038d7SDag-Erling Smørgrav type_count++; 809*7b5038d7SDag-Erling Smørgrav } 810*7b5038d7SDag-Erling Smørgrav cur_rrsets = cur_rrsets->next; 811*7b5038d7SDag-Erling Smørgrav 812*7b5038d7SDag-Erling Smørgrav } 813*7b5038d7SDag-Erling Smørgrav types[type_count] = LDNS_RR_TYPE_RRSIG; 814*7b5038d7SDag-Erling Smørgrav type_count++; 815*7b5038d7SDag-Erling Smørgrav types[type_count] = LDNS_RR_TYPE_NSEC; 816*7b5038d7SDag-Erling Smørgrav type_count++; 817*7b5038d7SDag-Erling Smørgrav 818*7b5038d7SDag-Erling Smørgrav ldns_rr_push_rdf(nsec_rr, ldns_dnssec_create_nsec_bitmap(types, 819*7b5038d7SDag-Erling Smørgrav type_count, 820*7b5038d7SDag-Erling Smørgrav nsec_type)); 821*7b5038d7SDag-Erling Smørgrav 822*7b5038d7SDag-Erling Smørgrav return nsec_rr; 823*7b5038d7SDag-Erling Smørgrav } 824*7b5038d7SDag-Erling Smørgrav 825*7b5038d7SDag-Erling Smørgrav ldns_rr * 826*7b5038d7SDag-Erling Smørgrav ldns_dnssec_create_nsec3(ldns_dnssec_name *from, 827*7b5038d7SDag-Erling Smørgrav ldns_dnssec_name *to, 828*7b5038d7SDag-Erling Smørgrav ldns_rdf *zone_name, 829*7b5038d7SDag-Erling Smørgrav uint8_t algorithm, 830*7b5038d7SDag-Erling Smørgrav uint8_t flags, 831*7b5038d7SDag-Erling Smørgrav uint16_t iterations, 832*7b5038d7SDag-Erling Smørgrav uint8_t salt_length, 833*7b5038d7SDag-Erling Smørgrav uint8_t *salt) 834*7b5038d7SDag-Erling Smørgrav { 835*7b5038d7SDag-Erling Smørgrav ldns_rr *nsec_rr; 836*7b5038d7SDag-Erling Smørgrav ldns_rr_type types[65536]; 837*7b5038d7SDag-Erling Smørgrav size_t type_count = 0; 838*7b5038d7SDag-Erling Smørgrav ldns_dnssec_rrsets *cur_rrsets; 839*7b5038d7SDag-Erling Smørgrav ldns_status status; 840*7b5038d7SDag-Erling Smørgrav int on_delegation_point; 841*7b5038d7SDag-Erling Smørgrav 842*7b5038d7SDag-Erling Smørgrav if (!from) { 843*7b5038d7SDag-Erling Smørgrav return NULL; 844*7b5038d7SDag-Erling Smørgrav } 845*7b5038d7SDag-Erling Smørgrav 846*7b5038d7SDag-Erling Smørgrav nsec_rr = ldns_rr_new_frm_type(LDNS_RR_TYPE_NSEC3); 847*7b5038d7SDag-Erling Smørgrav ldns_rr_set_owner(nsec_rr, 848*7b5038d7SDag-Erling Smørgrav ldns_nsec3_hash_name(ldns_dnssec_name_name(from), 849*7b5038d7SDag-Erling Smørgrav algorithm, 850*7b5038d7SDag-Erling Smørgrav iterations, 851*7b5038d7SDag-Erling Smørgrav salt_length, 852*7b5038d7SDag-Erling Smørgrav salt)); 853*7b5038d7SDag-Erling Smørgrav status = ldns_dname_cat(ldns_rr_owner(nsec_rr), zone_name); 854*7b5038d7SDag-Erling Smørgrav if(status != LDNS_STATUS_OK) { 855*7b5038d7SDag-Erling Smørgrav ldns_rr_free(nsec_rr); 856*7b5038d7SDag-Erling Smørgrav return NULL; 857*7b5038d7SDag-Erling Smørgrav } 858*7b5038d7SDag-Erling Smørgrav ldns_nsec3_add_param_rdfs(nsec_rr, 859*7b5038d7SDag-Erling Smørgrav algorithm, 860*7b5038d7SDag-Erling Smørgrav flags, 861*7b5038d7SDag-Erling Smørgrav iterations, 862*7b5038d7SDag-Erling Smørgrav salt_length, 863*7b5038d7SDag-Erling Smørgrav salt); 864*7b5038d7SDag-Erling Smørgrav 865*7b5038d7SDag-Erling Smørgrav on_delegation_point = ldns_dnssec_rrsets_contains_type( 866*7b5038d7SDag-Erling Smørgrav from->rrsets, LDNS_RR_TYPE_NS) 867*7b5038d7SDag-Erling Smørgrav && !ldns_dnssec_rrsets_contains_type( 868*7b5038d7SDag-Erling Smørgrav from->rrsets, LDNS_RR_TYPE_SOA); 869*7b5038d7SDag-Erling Smørgrav cur_rrsets = from->rrsets; 870*7b5038d7SDag-Erling Smørgrav while (cur_rrsets) { 871*7b5038d7SDag-Erling Smørgrav /* Do not include non-authoritative rrsets on the delegation point 872*7b5038d7SDag-Erling Smørgrav * in the type bitmap. Potentionally not skipping insecure 873*7b5038d7SDag-Erling Smørgrav * delegation should have been done earlier, in function 874*7b5038d7SDag-Erling Smørgrav * ldns_dnssec_zone_create_nsec3s, or even earlier in: 875*7b5038d7SDag-Erling Smørgrav * ldns_dnssec_zone_sign_nsec3_flg . 876*7b5038d7SDag-Erling Smørgrav */ 877*7b5038d7SDag-Erling Smørgrav if ((on_delegation_point && ( 878*7b5038d7SDag-Erling Smørgrav cur_rrsets->type == LDNS_RR_TYPE_NS 879*7b5038d7SDag-Erling Smørgrav || cur_rrsets->type == LDNS_RR_TYPE_DS)) 880*7b5038d7SDag-Erling Smørgrav || (!on_delegation_point && 881*7b5038d7SDag-Erling Smørgrav cur_rrsets->type != LDNS_RR_TYPE_RRSIG)) { 882*7b5038d7SDag-Erling Smørgrav 883*7b5038d7SDag-Erling Smørgrav types[type_count] = cur_rrsets->type; 884*7b5038d7SDag-Erling Smørgrav type_count++; 885*7b5038d7SDag-Erling Smørgrav } 886*7b5038d7SDag-Erling Smørgrav cur_rrsets = cur_rrsets->next; 887*7b5038d7SDag-Erling Smørgrav } 888*7b5038d7SDag-Erling Smørgrav /* always add rrsig type if this is not an unsigned 889*7b5038d7SDag-Erling Smørgrav * delegation 890*7b5038d7SDag-Erling Smørgrav */ 891*7b5038d7SDag-Erling Smørgrav if (type_count > 0 && 892*7b5038d7SDag-Erling Smørgrav !(type_count == 1 && types[0] == LDNS_RR_TYPE_NS)) { 893*7b5038d7SDag-Erling Smørgrav types[type_count] = LDNS_RR_TYPE_RRSIG; 894*7b5038d7SDag-Erling Smørgrav type_count++; 895*7b5038d7SDag-Erling Smørgrav } 896*7b5038d7SDag-Erling Smørgrav 897*7b5038d7SDag-Erling Smørgrav /* leave next rdata empty if they weren't precomputed yet */ 898*7b5038d7SDag-Erling Smørgrav if (to && to->hashed_name) { 899*7b5038d7SDag-Erling Smørgrav (void) ldns_rr_set_rdf(nsec_rr, 900*7b5038d7SDag-Erling Smørgrav ldns_rdf_clone(to->hashed_name), 901*7b5038d7SDag-Erling Smørgrav 4); 902*7b5038d7SDag-Erling Smørgrav } else { 903*7b5038d7SDag-Erling Smørgrav (void) ldns_rr_set_rdf(nsec_rr, NULL, 4); 904*7b5038d7SDag-Erling Smørgrav } 905*7b5038d7SDag-Erling Smørgrav 906*7b5038d7SDag-Erling Smørgrav ldns_rr_push_rdf(nsec_rr, 907*7b5038d7SDag-Erling Smørgrav ldns_dnssec_create_nsec_bitmap(types, 908*7b5038d7SDag-Erling Smørgrav type_count, 909*7b5038d7SDag-Erling Smørgrav LDNS_RR_TYPE_NSEC3)); 910*7b5038d7SDag-Erling Smørgrav 911*7b5038d7SDag-Erling Smørgrav return nsec_rr; 912*7b5038d7SDag-Erling Smørgrav } 913*7b5038d7SDag-Erling Smørgrav 914*7b5038d7SDag-Erling Smørgrav ldns_rr * 915*7b5038d7SDag-Erling Smørgrav ldns_create_nsec(ldns_rdf *cur_owner, ldns_rdf *next_owner, ldns_rr_list *rrs) 916*7b5038d7SDag-Erling Smørgrav { 917*7b5038d7SDag-Erling Smørgrav /* we do not do any check here - garbage in, garbage out */ 918*7b5038d7SDag-Erling Smørgrav 919*7b5038d7SDag-Erling Smørgrav /* the the start and end names - get the type from the 920*7b5038d7SDag-Erling Smørgrav * before rrlist */ 921*7b5038d7SDag-Erling Smørgrav 922*7b5038d7SDag-Erling Smørgrav /* inefficient, just give it a name, a next name, and a list of rrs */ 923*7b5038d7SDag-Erling Smørgrav /* we make 1 big uberbitmap first, then windows */ 924*7b5038d7SDag-Erling Smørgrav /* todo: make something more efficient :) */ 925*7b5038d7SDag-Erling Smørgrav uint16_t i; 926*7b5038d7SDag-Erling Smørgrav ldns_rr *i_rr; 927*7b5038d7SDag-Erling Smørgrav uint16_t i_type; 928*7b5038d7SDag-Erling Smørgrav 929*7b5038d7SDag-Erling Smørgrav ldns_rr *nsec = NULL; 930*7b5038d7SDag-Erling Smørgrav ldns_rr_type i_type_list[65536]; 931*7b5038d7SDag-Erling Smørgrav size_t type_count = 0; 932*7b5038d7SDag-Erling Smørgrav 933*7b5038d7SDag-Erling Smørgrav nsec = ldns_rr_new(); 934*7b5038d7SDag-Erling Smørgrav ldns_rr_set_type(nsec, LDNS_RR_TYPE_NSEC); 935*7b5038d7SDag-Erling Smørgrav ldns_rr_set_owner(nsec, ldns_rdf_clone(cur_owner)); 936*7b5038d7SDag-Erling Smørgrav ldns_rr_push_rdf(nsec, ldns_rdf_clone(next_owner)); 937*7b5038d7SDag-Erling Smørgrav 938*7b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(rrs); i++) { 939*7b5038d7SDag-Erling Smørgrav i_rr = ldns_rr_list_rr(rrs, i); 940*7b5038d7SDag-Erling Smørgrav if (ldns_rdf_compare(cur_owner, 941*7b5038d7SDag-Erling Smørgrav ldns_rr_owner(i_rr)) == 0) { 942*7b5038d7SDag-Erling Smørgrav i_type = ldns_rr_get_type(i_rr); 943*7b5038d7SDag-Erling Smørgrav if (i_type != LDNS_RR_TYPE_RRSIG && i_type != LDNS_RR_TYPE_NSEC) { 944*7b5038d7SDag-Erling Smørgrav if (type_count == 0 || i_type_list[type_count-1] != i_type) { 945*7b5038d7SDag-Erling Smørgrav i_type_list[type_count] = i_type; 946*7b5038d7SDag-Erling Smørgrav type_count++; 947*7b5038d7SDag-Erling Smørgrav } 948*7b5038d7SDag-Erling Smørgrav } 949*7b5038d7SDag-Erling Smørgrav } 950*7b5038d7SDag-Erling Smørgrav } 951*7b5038d7SDag-Erling Smørgrav 952*7b5038d7SDag-Erling Smørgrav i_type_list[type_count] = LDNS_RR_TYPE_RRSIG; 953*7b5038d7SDag-Erling Smørgrav type_count++; 954*7b5038d7SDag-Erling Smørgrav i_type_list[type_count] = LDNS_RR_TYPE_NSEC; 955*7b5038d7SDag-Erling Smørgrav type_count++; 956*7b5038d7SDag-Erling Smørgrav 957*7b5038d7SDag-Erling Smørgrav ldns_rr_push_rdf(nsec, 958*7b5038d7SDag-Erling Smørgrav ldns_dnssec_create_nsec_bitmap(i_type_list, 959*7b5038d7SDag-Erling Smørgrav type_count, LDNS_RR_TYPE_NSEC)); 960*7b5038d7SDag-Erling Smørgrav 961*7b5038d7SDag-Erling Smørgrav return nsec; 962*7b5038d7SDag-Erling Smørgrav } 963*7b5038d7SDag-Erling Smørgrav 964*7b5038d7SDag-Erling Smørgrav ldns_rdf * 965*7b5038d7SDag-Erling Smørgrav ldns_nsec3_hash_name(ldns_rdf *name, 966*7b5038d7SDag-Erling Smørgrav uint8_t algorithm, 967*7b5038d7SDag-Erling Smørgrav uint16_t iterations, 968*7b5038d7SDag-Erling Smørgrav uint8_t salt_length, 969*7b5038d7SDag-Erling Smørgrav uint8_t *salt) 970*7b5038d7SDag-Erling Smørgrav { 971*7b5038d7SDag-Erling Smørgrav size_t hashed_owner_str_len; 972*7b5038d7SDag-Erling Smørgrav ldns_rdf *cann; 973*7b5038d7SDag-Erling Smørgrav ldns_rdf *hashed_owner; 974*7b5038d7SDag-Erling Smørgrav unsigned char *hashed_owner_str; 975*7b5038d7SDag-Erling Smørgrav char *hashed_owner_b32; 976*7b5038d7SDag-Erling Smørgrav size_t hashed_owner_b32_len; 977*7b5038d7SDag-Erling Smørgrav uint32_t cur_it; 978*7b5038d7SDag-Erling Smørgrav /* define to contain the largest possible hash, which is 979*7b5038d7SDag-Erling Smørgrav * sha1 at the moment */ 980*7b5038d7SDag-Erling Smørgrav unsigned char hash[LDNS_SHA1_DIGEST_LENGTH]; 981*7b5038d7SDag-Erling Smørgrav ldns_status status; 982*7b5038d7SDag-Erling Smørgrav 983*7b5038d7SDag-Erling Smørgrav /* TODO: mnemonic list for hash algs SHA-1, default to 1 now (sha1) */ 984*7b5038d7SDag-Erling Smørgrav if (algorithm != LDNS_SHA1) { 985*7b5038d7SDag-Erling Smørgrav return NULL; 986*7b5038d7SDag-Erling Smørgrav } 987*7b5038d7SDag-Erling Smørgrav 988*7b5038d7SDag-Erling Smørgrav /* prepare the owner name according to the draft section bla */ 989*7b5038d7SDag-Erling Smørgrav cann = ldns_rdf_clone(name); 990*7b5038d7SDag-Erling Smørgrav if(!cann) { 991*7b5038d7SDag-Erling Smørgrav fprintf(stderr, "Memory error\n"); 992*7b5038d7SDag-Erling Smørgrav return NULL; 993*7b5038d7SDag-Erling Smørgrav } 994*7b5038d7SDag-Erling Smørgrav ldns_dname2canonical(cann); 995*7b5038d7SDag-Erling Smørgrav 996*7b5038d7SDag-Erling Smørgrav hashed_owner_str_len = salt_length + ldns_rdf_size(cann); 997*7b5038d7SDag-Erling Smørgrav hashed_owner_str = LDNS_XMALLOC(unsigned char, hashed_owner_str_len); 998*7b5038d7SDag-Erling Smørgrav if(!hashed_owner_str) { 999*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(cann); 1000*7b5038d7SDag-Erling Smørgrav return NULL; 1001*7b5038d7SDag-Erling Smørgrav } 1002*7b5038d7SDag-Erling Smørgrav memcpy(hashed_owner_str, ldns_rdf_data(cann), ldns_rdf_size(cann)); 1003*7b5038d7SDag-Erling Smørgrav memcpy(hashed_owner_str + ldns_rdf_size(cann), salt, salt_length); 1004*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(cann); 1005*7b5038d7SDag-Erling Smørgrav 1006*7b5038d7SDag-Erling Smørgrav for (cur_it = iterations + 1; cur_it > 0; cur_it--) { 1007*7b5038d7SDag-Erling Smørgrav (void) ldns_sha1((unsigned char *) hashed_owner_str, 1008*7b5038d7SDag-Erling Smørgrav (unsigned int) hashed_owner_str_len, hash); 1009*7b5038d7SDag-Erling Smørgrav 1010*7b5038d7SDag-Erling Smørgrav LDNS_FREE(hashed_owner_str); 1011*7b5038d7SDag-Erling Smørgrav hashed_owner_str_len = salt_length + LDNS_SHA1_DIGEST_LENGTH; 1012*7b5038d7SDag-Erling Smørgrav hashed_owner_str = LDNS_XMALLOC(unsigned char, hashed_owner_str_len); 1013*7b5038d7SDag-Erling Smørgrav if (!hashed_owner_str) { 1014*7b5038d7SDag-Erling Smørgrav return NULL; 1015*7b5038d7SDag-Erling Smørgrav } 1016*7b5038d7SDag-Erling Smørgrav memcpy(hashed_owner_str, hash, LDNS_SHA1_DIGEST_LENGTH); 1017*7b5038d7SDag-Erling Smørgrav memcpy(hashed_owner_str + LDNS_SHA1_DIGEST_LENGTH, salt, salt_length); 1018*7b5038d7SDag-Erling Smørgrav hashed_owner_str_len = LDNS_SHA1_DIGEST_LENGTH + salt_length; 1019*7b5038d7SDag-Erling Smørgrav } 1020*7b5038d7SDag-Erling Smørgrav 1021*7b5038d7SDag-Erling Smørgrav LDNS_FREE(hashed_owner_str); 1022*7b5038d7SDag-Erling Smørgrav hashed_owner_str = hash; 1023*7b5038d7SDag-Erling Smørgrav hashed_owner_str_len = LDNS_SHA1_DIGEST_LENGTH; 1024*7b5038d7SDag-Erling Smørgrav 1025*7b5038d7SDag-Erling Smørgrav hashed_owner_b32 = LDNS_XMALLOC(char, 1026*7b5038d7SDag-Erling Smørgrav ldns_b32_ntop_calculate_size(hashed_owner_str_len) + 1); 1027*7b5038d7SDag-Erling Smørgrav if(!hashed_owner_b32) { 1028*7b5038d7SDag-Erling Smørgrav return NULL; 1029*7b5038d7SDag-Erling Smørgrav } 1030*7b5038d7SDag-Erling Smørgrav hashed_owner_b32_len = (size_t) ldns_b32_ntop_extended_hex( 1031*7b5038d7SDag-Erling Smørgrav (uint8_t *) hashed_owner_str, 1032*7b5038d7SDag-Erling Smørgrav hashed_owner_str_len, 1033*7b5038d7SDag-Erling Smørgrav hashed_owner_b32, 1034*7b5038d7SDag-Erling Smørgrav ldns_b32_ntop_calculate_size(hashed_owner_str_len)+1); 1035*7b5038d7SDag-Erling Smørgrav if (hashed_owner_b32_len < 1) { 1036*7b5038d7SDag-Erling Smørgrav fprintf(stderr, "Error in base32 extended hex encoding "); 1037*7b5038d7SDag-Erling Smørgrav fprintf(stderr, "of hashed owner name (name: "); 1038*7b5038d7SDag-Erling Smørgrav ldns_rdf_print(stderr, name); 1039*7b5038d7SDag-Erling Smørgrav fprintf(stderr, ", return code: %u)\n", 1040*7b5038d7SDag-Erling Smørgrav (unsigned int) hashed_owner_b32_len); 1041*7b5038d7SDag-Erling Smørgrav LDNS_FREE(hashed_owner_b32); 1042*7b5038d7SDag-Erling Smørgrav return NULL; 1043*7b5038d7SDag-Erling Smørgrav } 1044*7b5038d7SDag-Erling Smørgrav hashed_owner_b32[hashed_owner_b32_len] = '\0'; 1045*7b5038d7SDag-Erling Smørgrav 1046*7b5038d7SDag-Erling Smørgrav status = ldns_str2rdf_dname(&hashed_owner, hashed_owner_b32); 1047*7b5038d7SDag-Erling Smørgrav if (status != LDNS_STATUS_OK) { 1048*7b5038d7SDag-Erling Smørgrav fprintf(stderr, "Error creating rdf from %s\n", hashed_owner_b32); 1049*7b5038d7SDag-Erling Smørgrav LDNS_FREE(hashed_owner_b32); 1050*7b5038d7SDag-Erling Smørgrav return NULL; 1051*7b5038d7SDag-Erling Smørgrav } 1052*7b5038d7SDag-Erling Smørgrav 1053*7b5038d7SDag-Erling Smørgrav LDNS_FREE(hashed_owner_b32); 1054*7b5038d7SDag-Erling Smørgrav return hashed_owner; 1055*7b5038d7SDag-Erling Smørgrav } 1056*7b5038d7SDag-Erling Smørgrav 1057*7b5038d7SDag-Erling Smørgrav void 1058*7b5038d7SDag-Erling Smørgrav ldns_nsec3_add_param_rdfs(ldns_rr *rr, 1059*7b5038d7SDag-Erling Smørgrav uint8_t algorithm, 1060*7b5038d7SDag-Erling Smørgrav uint8_t flags, 1061*7b5038d7SDag-Erling Smørgrav uint16_t iterations, 1062*7b5038d7SDag-Erling Smørgrav uint8_t salt_length, 1063*7b5038d7SDag-Erling Smørgrav uint8_t *salt) 1064*7b5038d7SDag-Erling Smørgrav { 1065*7b5038d7SDag-Erling Smørgrav ldns_rdf *salt_rdf = NULL; 1066*7b5038d7SDag-Erling Smørgrav uint8_t *salt_data = NULL; 1067*7b5038d7SDag-Erling Smørgrav ldns_rdf *old; 1068*7b5038d7SDag-Erling Smørgrav 1069*7b5038d7SDag-Erling Smørgrav old = ldns_rr_set_rdf(rr, 1070*7b5038d7SDag-Erling Smørgrav ldns_rdf_new_frm_data(LDNS_RDF_TYPE_INT8, 1071*7b5038d7SDag-Erling Smørgrav 1, (void*)&algorithm), 1072*7b5038d7SDag-Erling Smørgrav 0); 1073*7b5038d7SDag-Erling Smørgrav if (old) ldns_rdf_deep_free(old); 1074*7b5038d7SDag-Erling Smørgrav 1075*7b5038d7SDag-Erling Smørgrav old = ldns_rr_set_rdf(rr, 1076*7b5038d7SDag-Erling Smørgrav ldns_rdf_new_frm_data(LDNS_RDF_TYPE_INT8, 1077*7b5038d7SDag-Erling Smørgrav 1, (void*)&flags), 1078*7b5038d7SDag-Erling Smørgrav 1); 1079*7b5038d7SDag-Erling Smørgrav if (old) ldns_rdf_deep_free(old); 1080*7b5038d7SDag-Erling Smørgrav 1081*7b5038d7SDag-Erling Smørgrav old = ldns_rr_set_rdf(rr, 1082*7b5038d7SDag-Erling Smørgrav ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16, 1083*7b5038d7SDag-Erling Smørgrav iterations), 1084*7b5038d7SDag-Erling Smørgrav 2); 1085*7b5038d7SDag-Erling Smørgrav if (old) ldns_rdf_deep_free(old); 1086*7b5038d7SDag-Erling Smørgrav 1087*7b5038d7SDag-Erling Smørgrav salt_data = LDNS_XMALLOC(uint8_t, salt_length + 1); 1088*7b5038d7SDag-Erling Smørgrav if(!salt_data) { 1089*7b5038d7SDag-Erling Smørgrav /* no way to return error */ 1090*7b5038d7SDag-Erling Smørgrav return; 1091*7b5038d7SDag-Erling Smørgrav } 1092*7b5038d7SDag-Erling Smørgrav salt_data[0] = salt_length; 1093*7b5038d7SDag-Erling Smørgrav memcpy(salt_data + 1, salt, salt_length); 1094*7b5038d7SDag-Erling Smørgrav salt_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_NSEC3_SALT, 1095*7b5038d7SDag-Erling Smørgrav salt_length + 1, 1096*7b5038d7SDag-Erling Smørgrav salt_data); 1097*7b5038d7SDag-Erling Smørgrav if(!salt_rdf) { 1098*7b5038d7SDag-Erling Smørgrav LDNS_FREE(salt_data); 1099*7b5038d7SDag-Erling Smørgrav /* no way to return error */ 1100*7b5038d7SDag-Erling Smørgrav return; 1101*7b5038d7SDag-Erling Smørgrav } 1102*7b5038d7SDag-Erling Smørgrav 1103*7b5038d7SDag-Erling Smørgrav old = ldns_rr_set_rdf(rr, salt_rdf, 3); 1104*7b5038d7SDag-Erling Smørgrav if (old) ldns_rdf_deep_free(old); 1105*7b5038d7SDag-Erling Smørgrav LDNS_FREE(salt_data); 1106*7b5038d7SDag-Erling Smørgrav } 1107*7b5038d7SDag-Erling Smørgrav 1108*7b5038d7SDag-Erling Smørgrav static int 1109*7b5038d7SDag-Erling Smørgrav rr_list_delegation_only(ldns_rdf *origin, ldns_rr_list *rr_list) 1110*7b5038d7SDag-Erling Smørgrav { 1111*7b5038d7SDag-Erling Smørgrav size_t i; 1112*7b5038d7SDag-Erling Smørgrav ldns_rr *cur_rr; 1113*7b5038d7SDag-Erling Smørgrav if (!origin || !rr_list) return 0; 1114*7b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) { 1115*7b5038d7SDag-Erling Smørgrav cur_rr = ldns_rr_list_rr(rr_list, i); 1116*7b5038d7SDag-Erling Smørgrav if (ldns_dname_compare(ldns_rr_owner(cur_rr), origin) == 0) { 1117*7b5038d7SDag-Erling Smørgrav return 0; 1118*7b5038d7SDag-Erling Smørgrav } 1119*7b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(cur_rr) != LDNS_RR_TYPE_NS) { 1120*7b5038d7SDag-Erling Smørgrav return 0; 1121*7b5038d7SDag-Erling Smørgrav } 1122*7b5038d7SDag-Erling Smørgrav } 1123*7b5038d7SDag-Erling Smørgrav return 1; 1124*7b5038d7SDag-Erling Smørgrav } 1125*7b5038d7SDag-Erling Smørgrav 1126*7b5038d7SDag-Erling Smørgrav /* this will NOT return the NSEC3 completed, you will have to run the 1127*7b5038d7SDag-Erling Smørgrav finalize function on the rrlist later! */ 1128*7b5038d7SDag-Erling Smørgrav ldns_rr * 1129*7b5038d7SDag-Erling Smørgrav ldns_create_nsec3(ldns_rdf *cur_owner, 1130*7b5038d7SDag-Erling Smørgrav ldns_rdf *cur_zone, 1131*7b5038d7SDag-Erling Smørgrav ldns_rr_list *rrs, 1132*7b5038d7SDag-Erling Smørgrav uint8_t algorithm, 1133*7b5038d7SDag-Erling Smørgrav uint8_t flags, 1134*7b5038d7SDag-Erling Smørgrav uint16_t iterations, 1135*7b5038d7SDag-Erling Smørgrav uint8_t salt_length, 1136*7b5038d7SDag-Erling Smørgrav uint8_t *salt, 1137*7b5038d7SDag-Erling Smørgrav bool emptynonterminal) 1138*7b5038d7SDag-Erling Smørgrav { 1139*7b5038d7SDag-Erling Smørgrav size_t i; 1140*7b5038d7SDag-Erling Smørgrav ldns_rr *i_rr; 1141*7b5038d7SDag-Erling Smørgrav uint16_t i_type; 1142*7b5038d7SDag-Erling Smørgrav 1143*7b5038d7SDag-Erling Smørgrav ldns_rr *nsec = NULL; 1144*7b5038d7SDag-Erling Smørgrav ldns_rdf *hashed_owner = NULL; 1145*7b5038d7SDag-Erling Smørgrav 1146*7b5038d7SDag-Erling Smørgrav ldns_status status; 1147*7b5038d7SDag-Erling Smørgrav 1148*7b5038d7SDag-Erling Smørgrav ldns_rr_type i_type_list[1024]; 1149*7b5038d7SDag-Erling Smørgrav size_t type_count = 0; 1150*7b5038d7SDag-Erling Smørgrav 1151*7b5038d7SDag-Erling Smørgrav hashed_owner = ldns_nsec3_hash_name(cur_owner, 1152*7b5038d7SDag-Erling Smørgrav algorithm, 1153*7b5038d7SDag-Erling Smørgrav iterations, 1154*7b5038d7SDag-Erling Smørgrav salt_length, 1155*7b5038d7SDag-Erling Smørgrav salt); 1156*7b5038d7SDag-Erling Smørgrav status = ldns_dname_cat(hashed_owner, cur_zone); 1157*7b5038d7SDag-Erling Smørgrav if(status != LDNS_STATUS_OK) 1158*7b5038d7SDag-Erling Smørgrav return NULL; 1159*7b5038d7SDag-Erling Smørgrav 1160*7b5038d7SDag-Erling Smørgrav nsec = ldns_rr_new_frm_type(LDNS_RR_TYPE_NSEC3); 1161*7b5038d7SDag-Erling Smørgrav if(!nsec) 1162*7b5038d7SDag-Erling Smørgrav return NULL; 1163*7b5038d7SDag-Erling Smørgrav ldns_rr_set_type(nsec, LDNS_RR_TYPE_NSEC3); 1164*7b5038d7SDag-Erling Smørgrav ldns_rr_set_owner(nsec, hashed_owner); 1165*7b5038d7SDag-Erling Smørgrav 1166*7b5038d7SDag-Erling Smørgrav ldns_nsec3_add_param_rdfs(nsec, 1167*7b5038d7SDag-Erling Smørgrav algorithm, 1168*7b5038d7SDag-Erling Smørgrav flags, 1169*7b5038d7SDag-Erling Smørgrav iterations, 1170*7b5038d7SDag-Erling Smørgrav salt_length, 1171*7b5038d7SDag-Erling Smørgrav salt); 1172*7b5038d7SDag-Erling Smørgrav (void) ldns_rr_set_rdf(nsec, NULL, 4); 1173*7b5038d7SDag-Erling Smørgrav 1174*7b5038d7SDag-Erling Smørgrav 1175*7b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(rrs); i++) { 1176*7b5038d7SDag-Erling Smørgrav i_rr = ldns_rr_list_rr(rrs, i); 1177*7b5038d7SDag-Erling Smørgrav if (ldns_rdf_compare(cur_owner, 1178*7b5038d7SDag-Erling Smørgrav ldns_rr_owner(i_rr)) == 0) { 1179*7b5038d7SDag-Erling Smørgrav i_type = ldns_rr_get_type(i_rr); 1180*7b5038d7SDag-Erling Smørgrav if (type_count == 0 || i_type_list[type_count-1] != i_type) { 1181*7b5038d7SDag-Erling Smørgrav i_type_list[type_count] = i_type; 1182*7b5038d7SDag-Erling Smørgrav type_count++; 1183*7b5038d7SDag-Erling Smørgrav } 1184*7b5038d7SDag-Erling Smørgrav } 1185*7b5038d7SDag-Erling Smørgrav } 1186*7b5038d7SDag-Erling Smørgrav 1187*7b5038d7SDag-Erling Smørgrav /* add RRSIG anyway, but only if this is not an ENT or 1188*7b5038d7SDag-Erling Smørgrav * an unsigned delegation */ 1189*7b5038d7SDag-Erling Smørgrav if (!emptynonterminal && !rr_list_delegation_only(cur_zone, rrs)) { 1190*7b5038d7SDag-Erling Smørgrav i_type_list[type_count] = LDNS_RR_TYPE_RRSIG; 1191*7b5038d7SDag-Erling Smørgrav type_count++; 1192*7b5038d7SDag-Erling Smørgrav } 1193*7b5038d7SDag-Erling Smørgrav 1194*7b5038d7SDag-Erling Smørgrav /* and SOA if owner == zone */ 1195*7b5038d7SDag-Erling Smørgrav if (ldns_dname_compare(cur_zone, cur_owner) == 0) { 1196*7b5038d7SDag-Erling Smørgrav i_type_list[type_count] = LDNS_RR_TYPE_SOA; 1197*7b5038d7SDag-Erling Smørgrav type_count++; 1198*7b5038d7SDag-Erling Smørgrav } 1199*7b5038d7SDag-Erling Smørgrav 1200*7b5038d7SDag-Erling Smørgrav ldns_rr_push_rdf(nsec, 1201*7b5038d7SDag-Erling Smørgrav ldns_dnssec_create_nsec_bitmap(i_type_list, 1202*7b5038d7SDag-Erling Smørgrav type_count, LDNS_RR_TYPE_NSEC3)); 1203*7b5038d7SDag-Erling Smørgrav 1204*7b5038d7SDag-Erling Smørgrav return nsec; 1205*7b5038d7SDag-Erling Smørgrav } 1206*7b5038d7SDag-Erling Smørgrav 1207*7b5038d7SDag-Erling Smørgrav uint8_t 1208*7b5038d7SDag-Erling Smørgrav ldns_nsec3_algorithm(const ldns_rr *nsec3_rr) 1209*7b5038d7SDag-Erling Smørgrav { 1210*7b5038d7SDag-Erling Smørgrav if (nsec3_rr && 1211*7b5038d7SDag-Erling Smørgrav (ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3 || 1212*7b5038d7SDag-Erling Smørgrav ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3PARAM) 1213*7b5038d7SDag-Erling Smørgrav && (ldns_rr_rdf(nsec3_rr, 0) != NULL) 1214*7b5038d7SDag-Erling Smørgrav && ldns_rdf_size(ldns_rr_rdf(nsec3_rr, 0)) > 0) { 1215*7b5038d7SDag-Erling Smørgrav return ldns_rdf2native_int8(ldns_rr_rdf(nsec3_rr, 0)); 1216*7b5038d7SDag-Erling Smørgrav } 1217*7b5038d7SDag-Erling Smørgrav return 0; 1218*7b5038d7SDag-Erling Smørgrav } 1219*7b5038d7SDag-Erling Smørgrav 1220*7b5038d7SDag-Erling Smørgrav uint8_t 1221*7b5038d7SDag-Erling Smørgrav ldns_nsec3_flags(const ldns_rr *nsec3_rr) 1222*7b5038d7SDag-Erling Smørgrav { 1223*7b5038d7SDag-Erling Smørgrav if (nsec3_rr && 1224*7b5038d7SDag-Erling Smørgrav (ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3 || 1225*7b5038d7SDag-Erling Smørgrav ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3PARAM) 1226*7b5038d7SDag-Erling Smørgrav && (ldns_rr_rdf(nsec3_rr, 1) != NULL) 1227*7b5038d7SDag-Erling Smørgrav && ldns_rdf_size(ldns_rr_rdf(nsec3_rr, 1)) > 0) { 1228*7b5038d7SDag-Erling Smørgrav return ldns_rdf2native_int8(ldns_rr_rdf(nsec3_rr, 1)); 1229*7b5038d7SDag-Erling Smørgrav } 1230*7b5038d7SDag-Erling Smørgrav return 0; 1231*7b5038d7SDag-Erling Smørgrav } 1232*7b5038d7SDag-Erling Smørgrav 1233*7b5038d7SDag-Erling Smørgrav bool 1234*7b5038d7SDag-Erling Smørgrav ldns_nsec3_optout(const ldns_rr *nsec3_rr) 1235*7b5038d7SDag-Erling Smørgrav { 1236*7b5038d7SDag-Erling Smørgrav return (ldns_nsec3_flags(nsec3_rr) & LDNS_NSEC3_VARS_OPTOUT_MASK); 1237*7b5038d7SDag-Erling Smørgrav } 1238*7b5038d7SDag-Erling Smørgrav 1239*7b5038d7SDag-Erling Smørgrav uint16_t 1240*7b5038d7SDag-Erling Smørgrav ldns_nsec3_iterations(const ldns_rr *nsec3_rr) 1241*7b5038d7SDag-Erling Smørgrav { 1242*7b5038d7SDag-Erling Smørgrav if (nsec3_rr && 1243*7b5038d7SDag-Erling Smørgrav (ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3 || 1244*7b5038d7SDag-Erling Smørgrav ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3PARAM) 1245*7b5038d7SDag-Erling Smørgrav && (ldns_rr_rdf(nsec3_rr, 2) != NULL) 1246*7b5038d7SDag-Erling Smørgrav && ldns_rdf_size(ldns_rr_rdf(nsec3_rr, 2)) > 0) { 1247*7b5038d7SDag-Erling Smørgrav return ldns_rdf2native_int16(ldns_rr_rdf(nsec3_rr, 2)); 1248*7b5038d7SDag-Erling Smørgrav } 1249*7b5038d7SDag-Erling Smørgrav return 0; 1250*7b5038d7SDag-Erling Smørgrav 1251*7b5038d7SDag-Erling Smørgrav } 1252*7b5038d7SDag-Erling Smørgrav 1253*7b5038d7SDag-Erling Smørgrav ldns_rdf * 1254*7b5038d7SDag-Erling Smørgrav ldns_nsec3_salt(const ldns_rr *nsec3_rr) 1255*7b5038d7SDag-Erling Smørgrav { 1256*7b5038d7SDag-Erling Smørgrav if (nsec3_rr && 1257*7b5038d7SDag-Erling Smørgrav (ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3 || 1258*7b5038d7SDag-Erling Smørgrav ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3PARAM) 1259*7b5038d7SDag-Erling Smørgrav ) { 1260*7b5038d7SDag-Erling Smørgrav return ldns_rr_rdf(nsec3_rr, 3); 1261*7b5038d7SDag-Erling Smørgrav } 1262*7b5038d7SDag-Erling Smørgrav return NULL; 1263*7b5038d7SDag-Erling Smørgrav } 1264*7b5038d7SDag-Erling Smørgrav 1265*7b5038d7SDag-Erling Smørgrav uint8_t 1266*7b5038d7SDag-Erling Smørgrav ldns_nsec3_salt_length(const ldns_rr *nsec3_rr) 1267*7b5038d7SDag-Erling Smørgrav { 1268*7b5038d7SDag-Erling Smørgrav ldns_rdf *salt_rdf = ldns_nsec3_salt(nsec3_rr); 1269*7b5038d7SDag-Erling Smørgrav if (salt_rdf && ldns_rdf_size(salt_rdf) > 0) { 1270*7b5038d7SDag-Erling Smørgrav return (uint8_t) ldns_rdf_data(salt_rdf)[0]; 1271*7b5038d7SDag-Erling Smørgrav } 1272*7b5038d7SDag-Erling Smørgrav return 0; 1273*7b5038d7SDag-Erling Smørgrav } 1274*7b5038d7SDag-Erling Smørgrav 1275*7b5038d7SDag-Erling Smørgrav /* allocs data, free with LDNS_FREE() */ 1276*7b5038d7SDag-Erling Smørgrav uint8_t * 1277*7b5038d7SDag-Erling Smørgrav ldns_nsec3_salt_data(const ldns_rr *nsec3_rr) 1278*7b5038d7SDag-Erling Smørgrav { 1279*7b5038d7SDag-Erling Smørgrav uint8_t salt_length; 1280*7b5038d7SDag-Erling Smørgrav uint8_t *salt; 1281*7b5038d7SDag-Erling Smørgrav 1282*7b5038d7SDag-Erling Smørgrav ldns_rdf *salt_rdf = ldns_nsec3_salt(nsec3_rr); 1283*7b5038d7SDag-Erling Smørgrav if (salt_rdf && ldns_rdf_size(salt_rdf) > 0) { 1284*7b5038d7SDag-Erling Smørgrav salt_length = ldns_rdf_data(salt_rdf)[0]; 1285*7b5038d7SDag-Erling Smørgrav salt = LDNS_XMALLOC(uint8_t, salt_length); 1286*7b5038d7SDag-Erling Smørgrav if(!salt) return NULL; 1287*7b5038d7SDag-Erling Smørgrav memcpy(salt, &ldns_rdf_data(salt_rdf)[1], salt_length); 1288*7b5038d7SDag-Erling Smørgrav return salt; 1289*7b5038d7SDag-Erling Smørgrav } 1290*7b5038d7SDag-Erling Smørgrav return NULL; 1291*7b5038d7SDag-Erling Smørgrav } 1292*7b5038d7SDag-Erling Smørgrav 1293*7b5038d7SDag-Erling Smørgrav ldns_rdf * 1294*7b5038d7SDag-Erling Smørgrav ldns_nsec3_next_owner(const ldns_rr *nsec3_rr) 1295*7b5038d7SDag-Erling Smørgrav { 1296*7b5038d7SDag-Erling Smørgrav if (!nsec3_rr || ldns_rr_get_type(nsec3_rr) != LDNS_RR_TYPE_NSEC3) { 1297*7b5038d7SDag-Erling Smørgrav return NULL; 1298*7b5038d7SDag-Erling Smørgrav } else { 1299*7b5038d7SDag-Erling Smørgrav return ldns_rr_rdf(nsec3_rr, 4); 1300*7b5038d7SDag-Erling Smørgrav } 1301*7b5038d7SDag-Erling Smørgrav } 1302*7b5038d7SDag-Erling Smørgrav 1303*7b5038d7SDag-Erling Smørgrav ldns_rdf * 1304*7b5038d7SDag-Erling Smørgrav ldns_nsec3_bitmap(const ldns_rr *nsec3_rr) 1305*7b5038d7SDag-Erling Smørgrav { 1306*7b5038d7SDag-Erling Smørgrav if (!nsec3_rr || ldns_rr_get_type(nsec3_rr) != LDNS_RR_TYPE_NSEC3) { 1307*7b5038d7SDag-Erling Smørgrav return NULL; 1308*7b5038d7SDag-Erling Smørgrav } else { 1309*7b5038d7SDag-Erling Smørgrav return ldns_rr_rdf(nsec3_rr, 5); 1310*7b5038d7SDag-Erling Smørgrav } 1311*7b5038d7SDag-Erling Smørgrav } 1312*7b5038d7SDag-Erling Smørgrav 1313*7b5038d7SDag-Erling Smørgrav ldns_rdf * 1314*7b5038d7SDag-Erling Smørgrav ldns_nsec3_hash_name_frm_nsec3(const ldns_rr *nsec, ldns_rdf *name) 1315*7b5038d7SDag-Erling Smørgrav { 1316*7b5038d7SDag-Erling Smørgrav uint8_t algorithm; 1317*7b5038d7SDag-Erling Smørgrav uint16_t iterations; 1318*7b5038d7SDag-Erling Smørgrav uint8_t salt_length; 1319*7b5038d7SDag-Erling Smørgrav uint8_t *salt = 0; 1320*7b5038d7SDag-Erling Smørgrav 1321*7b5038d7SDag-Erling Smørgrav ldns_rdf *hashed_owner; 1322*7b5038d7SDag-Erling Smørgrav 1323*7b5038d7SDag-Erling Smørgrav algorithm = ldns_nsec3_algorithm(nsec); 1324*7b5038d7SDag-Erling Smørgrav salt_length = ldns_nsec3_salt_length(nsec); 1325*7b5038d7SDag-Erling Smørgrav salt = ldns_nsec3_salt_data(nsec); 1326*7b5038d7SDag-Erling Smørgrav iterations = ldns_nsec3_iterations(nsec); 1327*7b5038d7SDag-Erling Smørgrav 1328*7b5038d7SDag-Erling Smørgrav hashed_owner = ldns_nsec3_hash_name(name, 1329*7b5038d7SDag-Erling Smørgrav algorithm, 1330*7b5038d7SDag-Erling Smørgrav iterations, 1331*7b5038d7SDag-Erling Smørgrav salt_length, 1332*7b5038d7SDag-Erling Smørgrav salt); 1333*7b5038d7SDag-Erling Smørgrav 1334*7b5038d7SDag-Erling Smørgrav LDNS_FREE(salt); 1335*7b5038d7SDag-Erling Smørgrav return hashed_owner; 1336*7b5038d7SDag-Erling Smørgrav } 1337*7b5038d7SDag-Erling Smørgrav 1338*7b5038d7SDag-Erling Smørgrav bool 1339*7b5038d7SDag-Erling Smørgrav ldns_nsec_bitmap_covers_type(const ldns_rdf *nsec_bitmap, ldns_rr_type type) 1340*7b5038d7SDag-Erling Smørgrav { 1341*7b5038d7SDag-Erling Smørgrav uint8_t window_block_nr; 1342*7b5038d7SDag-Erling Smørgrav uint8_t bitmap_length; 1343*7b5038d7SDag-Erling Smørgrav uint16_t cur_type; 1344*7b5038d7SDag-Erling Smørgrav uint16_t pos = 0; 1345*7b5038d7SDag-Erling Smørgrav uint16_t bit_pos; 1346*7b5038d7SDag-Erling Smørgrav uint8_t *data; 1347*7b5038d7SDag-Erling Smørgrav 1348*7b5038d7SDag-Erling Smørgrav if (nsec_bitmap == NULL) { 1349*7b5038d7SDag-Erling Smørgrav return false; 1350*7b5038d7SDag-Erling Smørgrav } 1351*7b5038d7SDag-Erling Smørgrav data = ldns_rdf_data(nsec_bitmap); 1352*7b5038d7SDag-Erling Smørgrav while(pos < ldns_rdf_size(nsec_bitmap)) { 1353*7b5038d7SDag-Erling Smørgrav window_block_nr = data[pos]; 1354*7b5038d7SDag-Erling Smørgrav bitmap_length = data[pos + 1]; 1355*7b5038d7SDag-Erling Smørgrav pos += 2; 1356*7b5038d7SDag-Erling Smørgrav 1357*7b5038d7SDag-Erling Smørgrav for (bit_pos = 0; bit_pos < (bitmap_length) * 8; bit_pos++) { 1358*7b5038d7SDag-Erling Smørgrav if (ldns_get_bit(&data[pos], bit_pos)) { 1359*7b5038d7SDag-Erling Smørgrav cur_type = 256 * (uint16_t) window_block_nr + bit_pos; 1360*7b5038d7SDag-Erling Smørgrav if (cur_type == type) { 1361*7b5038d7SDag-Erling Smørgrav return true; 1362*7b5038d7SDag-Erling Smørgrav } 1363*7b5038d7SDag-Erling Smørgrav } 1364*7b5038d7SDag-Erling Smørgrav } 1365*7b5038d7SDag-Erling Smørgrav 1366*7b5038d7SDag-Erling Smørgrav pos += (uint16_t) bitmap_length; 1367*7b5038d7SDag-Erling Smørgrav } 1368*7b5038d7SDag-Erling Smørgrav return false; 1369*7b5038d7SDag-Erling Smørgrav } 1370*7b5038d7SDag-Erling Smørgrav 1371*7b5038d7SDag-Erling Smørgrav bool 1372*7b5038d7SDag-Erling Smørgrav ldns_nsec_covers_name(const ldns_rr *nsec, const ldns_rdf *name) 1373*7b5038d7SDag-Erling Smørgrav { 1374*7b5038d7SDag-Erling Smørgrav ldns_rdf *nsec_owner = ldns_rr_owner(nsec); 1375*7b5038d7SDag-Erling Smørgrav ldns_rdf *hash_next; 1376*7b5038d7SDag-Erling Smørgrav char *next_hash_str; 1377*7b5038d7SDag-Erling Smørgrav ldns_rdf *nsec_next = NULL; 1378*7b5038d7SDag-Erling Smørgrav ldns_status status; 1379*7b5038d7SDag-Erling Smørgrav ldns_rdf *chopped_dname; 1380*7b5038d7SDag-Erling Smørgrav bool result; 1381*7b5038d7SDag-Erling Smørgrav 1382*7b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(nsec) == LDNS_RR_TYPE_NSEC) { 1383*7b5038d7SDag-Erling Smørgrav if (ldns_rr_rdf(nsec, 0) != NULL) { 1384*7b5038d7SDag-Erling Smørgrav nsec_next = ldns_rdf_clone(ldns_rr_rdf(nsec, 0)); 1385*7b5038d7SDag-Erling Smørgrav } else { 1386*7b5038d7SDag-Erling Smørgrav return false; 1387*7b5038d7SDag-Erling Smørgrav } 1388*7b5038d7SDag-Erling Smørgrav } else if (ldns_rr_get_type(nsec) == LDNS_RR_TYPE_NSEC3) { 1389*7b5038d7SDag-Erling Smørgrav hash_next = ldns_nsec3_next_owner(nsec); 1390*7b5038d7SDag-Erling Smørgrav next_hash_str = ldns_rdf2str(hash_next); 1391*7b5038d7SDag-Erling Smørgrav nsec_next = ldns_dname_new_frm_str(next_hash_str); 1392*7b5038d7SDag-Erling Smørgrav LDNS_FREE(next_hash_str); 1393*7b5038d7SDag-Erling Smørgrav chopped_dname = ldns_dname_left_chop(nsec_owner); 1394*7b5038d7SDag-Erling Smørgrav status = ldns_dname_cat(nsec_next, chopped_dname); 1395*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(chopped_dname); 1396*7b5038d7SDag-Erling Smørgrav if (status != LDNS_STATUS_OK) { 1397*7b5038d7SDag-Erling Smørgrav printf("error catting: %s\n", ldns_get_errorstr_by_id(status)); 1398*7b5038d7SDag-Erling Smørgrav } 1399*7b5038d7SDag-Erling Smørgrav } else { 1400*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(nsec_next); 1401*7b5038d7SDag-Erling Smørgrav return false; 1402*7b5038d7SDag-Erling Smørgrav } 1403*7b5038d7SDag-Erling Smørgrav 1404*7b5038d7SDag-Erling Smørgrav /* in the case of the last nsec */ 1405*7b5038d7SDag-Erling Smørgrav if(ldns_dname_compare(nsec_owner, nsec_next) > 0) { 1406*7b5038d7SDag-Erling Smørgrav result = (ldns_dname_compare(nsec_owner, name) <= 0 || 1407*7b5038d7SDag-Erling Smørgrav ldns_dname_compare(name, nsec_next) < 0); 1408*7b5038d7SDag-Erling Smørgrav } else { 1409*7b5038d7SDag-Erling Smørgrav result = (ldns_dname_compare(nsec_owner, name) <= 0 && 1410*7b5038d7SDag-Erling Smørgrav ldns_dname_compare(name, nsec_next) < 0); 1411*7b5038d7SDag-Erling Smørgrav } 1412*7b5038d7SDag-Erling Smørgrav 1413*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(nsec_next); 1414*7b5038d7SDag-Erling Smørgrav return result; 1415*7b5038d7SDag-Erling Smørgrav } 1416*7b5038d7SDag-Erling Smørgrav 1417*7b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 1418*7b5038d7SDag-Erling Smørgrav /* sig may be null - if so look in the packet */ 1419*7b5038d7SDag-Erling Smørgrav 1420*7b5038d7SDag-Erling Smørgrav ldns_status 1421*7b5038d7SDag-Erling Smørgrav ldns_pkt_verify_time(ldns_pkt *p, ldns_rr_type t, ldns_rdf *o, 1422*7b5038d7SDag-Erling Smørgrav ldns_rr_list *k, ldns_rr_list *s, 1423*7b5038d7SDag-Erling Smørgrav time_t check_time, ldns_rr_list *good_keys) 1424*7b5038d7SDag-Erling Smørgrav { 1425*7b5038d7SDag-Erling Smørgrav ldns_rr_list *rrset; 1426*7b5038d7SDag-Erling Smørgrav ldns_rr_list *sigs; 1427*7b5038d7SDag-Erling Smørgrav ldns_rr_list *sigs_covered; 1428*7b5038d7SDag-Erling Smørgrav ldns_rdf *rdf_t; 1429*7b5038d7SDag-Erling Smørgrav ldns_rr_type t_netorder; 1430*7b5038d7SDag-Erling Smørgrav 1431*7b5038d7SDag-Erling Smørgrav if (!k) { 1432*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 1433*7b5038d7SDag-Erling Smørgrav /* return LDNS_STATUS_CRYPTO_NO_DNSKEY; */ 1434*7b5038d7SDag-Erling Smørgrav } 1435*7b5038d7SDag-Erling Smørgrav 1436*7b5038d7SDag-Erling Smørgrav if (t == LDNS_RR_TYPE_RRSIG) { 1437*7b5038d7SDag-Erling Smørgrav /* we don't have RRSIG(RRSIG) (yet? ;-) ) */ 1438*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 1439*7b5038d7SDag-Erling Smørgrav } 1440*7b5038d7SDag-Erling Smørgrav 1441*7b5038d7SDag-Erling Smørgrav if (s) { 1442*7b5038d7SDag-Erling Smørgrav /* if s is not NULL, the sigs are given to use */ 1443*7b5038d7SDag-Erling Smørgrav sigs = s; 1444*7b5038d7SDag-Erling Smørgrav } else { 1445*7b5038d7SDag-Erling Smørgrav /* otherwise get them from the packet */ 1446*7b5038d7SDag-Erling Smørgrav sigs = ldns_pkt_rr_list_by_name_and_type(p, o, LDNS_RR_TYPE_RRSIG, 1447*7b5038d7SDag-Erling Smørgrav LDNS_SECTION_ANY_NOQUESTION); 1448*7b5038d7SDag-Erling Smørgrav if (!sigs) { 1449*7b5038d7SDag-Erling Smørgrav /* no sigs */ 1450*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 1451*7b5038d7SDag-Erling Smørgrav /* return LDNS_STATUS_CRYPTO_NO_RRSIG; */ 1452*7b5038d7SDag-Erling Smørgrav } 1453*7b5038d7SDag-Erling Smørgrav } 1454*7b5038d7SDag-Erling Smørgrav 1455*7b5038d7SDag-Erling Smørgrav /* rrsig are subtyped, so now we need to find the correct 1456*7b5038d7SDag-Erling Smørgrav * sigs for the type t 1457*7b5038d7SDag-Erling Smørgrav */ 1458*7b5038d7SDag-Erling Smørgrav t_netorder = htons(t); /* rdf are in network order! */ 1459*7b5038d7SDag-Erling Smørgrav /* a type identifier is a 16-bit number, so the size is 2 bytes */ 1460*7b5038d7SDag-Erling Smørgrav rdf_t = ldns_rdf_new(LDNS_RDF_TYPE_TYPE, 1461*7b5038d7SDag-Erling Smørgrav 2, 1462*7b5038d7SDag-Erling Smørgrav &t_netorder); 1463*7b5038d7SDag-Erling Smørgrav sigs_covered = ldns_rr_list_subtype_by_rdf(sigs, rdf_t, 0); 1464*7b5038d7SDag-Erling Smørgrav 1465*7b5038d7SDag-Erling Smørgrav rrset = ldns_pkt_rr_list_by_name_and_type(p, 1466*7b5038d7SDag-Erling Smørgrav o, 1467*7b5038d7SDag-Erling Smørgrav t, 1468*7b5038d7SDag-Erling Smørgrav LDNS_SECTION_ANY_NOQUESTION); 1469*7b5038d7SDag-Erling Smørgrav 1470*7b5038d7SDag-Erling Smørgrav if (!rrset) { 1471*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 1472*7b5038d7SDag-Erling Smørgrav } 1473*7b5038d7SDag-Erling Smørgrav 1474*7b5038d7SDag-Erling Smørgrav if (!sigs_covered) { 1475*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 1476*7b5038d7SDag-Erling Smørgrav } 1477*7b5038d7SDag-Erling Smørgrav 1478*7b5038d7SDag-Erling Smørgrav return ldns_verify_time(rrset, sigs, k, check_time, good_keys); 1479*7b5038d7SDag-Erling Smørgrav } 1480*7b5038d7SDag-Erling Smørgrav 1481*7b5038d7SDag-Erling Smørgrav ldns_status 1482*7b5038d7SDag-Erling Smørgrav ldns_pkt_verify(ldns_pkt *p, ldns_rr_type t, ldns_rdf *o, 1483*7b5038d7SDag-Erling Smørgrav ldns_rr_list *k, ldns_rr_list *s, ldns_rr_list *good_keys) 1484*7b5038d7SDag-Erling Smørgrav { 1485*7b5038d7SDag-Erling Smørgrav return ldns_pkt_verify_time(p, t, o, k, s, ldns_time(NULL), good_keys); 1486*7b5038d7SDag-Erling Smørgrav } 1487*7b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 1488*7b5038d7SDag-Erling Smørgrav 1489*7b5038d7SDag-Erling Smørgrav ldns_status 1490*7b5038d7SDag-Erling Smørgrav ldns_dnssec_chain_nsec3_list(ldns_rr_list *nsec3_rrs) 1491*7b5038d7SDag-Erling Smørgrav { 1492*7b5038d7SDag-Erling Smørgrav size_t i; 1493*7b5038d7SDag-Erling Smørgrav char *next_nsec_owner_str; 1494*7b5038d7SDag-Erling Smørgrav ldns_rdf *next_nsec_owner_label; 1495*7b5038d7SDag-Erling Smørgrav ldns_rdf *next_nsec_rdf; 1496*7b5038d7SDag-Erling Smørgrav ldns_status status = LDNS_STATUS_OK; 1497*7b5038d7SDag-Erling Smørgrav 1498*7b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(nsec3_rrs); i++) { 1499*7b5038d7SDag-Erling Smørgrav if (i == ldns_rr_list_rr_count(nsec3_rrs) - 1) { 1500*7b5038d7SDag-Erling Smørgrav next_nsec_owner_label = 1501*7b5038d7SDag-Erling Smørgrav ldns_dname_label(ldns_rr_owner(ldns_rr_list_rr(nsec3_rrs, 1502*7b5038d7SDag-Erling Smørgrav 0)), 0); 1503*7b5038d7SDag-Erling Smørgrav next_nsec_owner_str = ldns_rdf2str(next_nsec_owner_label); 1504*7b5038d7SDag-Erling Smørgrav if (next_nsec_owner_str[strlen(next_nsec_owner_str) - 1] 1505*7b5038d7SDag-Erling Smørgrav == '.') { 1506*7b5038d7SDag-Erling Smørgrav next_nsec_owner_str[strlen(next_nsec_owner_str) - 1] 1507*7b5038d7SDag-Erling Smørgrav = '\0'; 1508*7b5038d7SDag-Erling Smørgrav } 1509*7b5038d7SDag-Erling Smørgrav status = ldns_str2rdf_b32_ext(&next_nsec_rdf, 1510*7b5038d7SDag-Erling Smørgrav next_nsec_owner_str); 1511*7b5038d7SDag-Erling Smørgrav if (!ldns_rr_set_rdf(ldns_rr_list_rr(nsec3_rrs, i), 1512*7b5038d7SDag-Erling Smørgrav next_nsec_rdf, 4)) { 1513*7b5038d7SDag-Erling Smørgrav /* todo: error */ 1514*7b5038d7SDag-Erling Smørgrav } 1515*7b5038d7SDag-Erling Smørgrav 1516*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(next_nsec_owner_label); 1517*7b5038d7SDag-Erling Smørgrav LDNS_FREE(next_nsec_owner_str); 1518*7b5038d7SDag-Erling Smørgrav } else { 1519*7b5038d7SDag-Erling Smørgrav next_nsec_owner_label = 1520*7b5038d7SDag-Erling Smørgrav ldns_dname_label(ldns_rr_owner(ldns_rr_list_rr(nsec3_rrs, 1521*7b5038d7SDag-Erling Smørgrav i + 1)), 1522*7b5038d7SDag-Erling Smørgrav 0); 1523*7b5038d7SDag-Erling Smørgrav next_nsec_owner_str = ldns_rdf2str(next_nsec_owner_label); 1524*7b5038d7SDag-Erling Smørgrav if (next_nsec_owner_str[strlen(next_nsec_owner_str) - 1] 1525*7b5038d7SDag-Erling Smørgrav == '.') { 1526*7b5038d7SDag-Erling Smørgrav next_nsec_owner_str[strlen(next_nsec_owner_str) - 1] 1527*7b5038d7SDag-Erling Smørgrav = '\0'; 1528*7b5038d7SDag-Erling Smørgrav } 1529*7b5038d7SDag-Erling Smørgrav status = ldns_str2rdf_b32_ext(&next_nsec_rdf, 1530*7b5038d7SDag-Erling Smørgrav next_nsec_owner_str); 1531*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(next_nsec_owner_label); 1532*7b5038d7SDag-Erling Smørgrav LDNS_FREE(next_nsec_owner_str); 1533*7b5038d7SDag-Erling Smørgrav if (!ldns_rr_set_rdf(ldns_rr_list_rr(nsec3_rrs, i), 1534*7b5038d7SDag-Erling Smørgrav next_nsec_rdf, 4)) { 1535*7b5038d7SDag-Erling Smørgrav /* todo: error */ 1536*7b5038d7SDag-Erling Smørgrav } 1537*7b5038d7SDag-Erling Smørgrav } 1538*7b5038d7SDag-Erling Smørgrav } 1539*7b5038d7SDag-Erling Smørgrav return status; 1540*7b5038d7SDag-Erling Smørgrav } 1541*7b5038d7SDag-Erling Smørgrav 1542*7b5038d7SDag-Erling Smørgrav int 1543*7b5038d7SDag-Erling Smørgrav qsort_rr_compare_nsec3(const void *a, const void *b) 1544*7b5038d7SDag-Erling Smørgrav { 1545*7b5038d7SDag-Erling Smørgrav const ldns_rr *rr1 = * (const ldns_rr **) a; 1546*7b5038d7SDag-Erling Smørgrav const ldns_rr *rr2 = * (const ldns_rr **) b; 1547*7b5038d7SDag-Erling Smørgrav if (rr1 == NULL && rr2 == NULL) { 1548*7b5038d7SDag-Erling Smørgrav return 0; 1549*7b5038d7SDag-Erling Smørgrav } 1550*7b5038d7SDag-Erling Smørgrav if (rr1 == NULL) { 1551*7b5038d7SDag-Erling Smørgrav return -1; 1552*7b5038d7SDag-Erling Smørgrav } 1553*7b5038d7SDag-Erling Smørgrav if (rr2 == NULL) { 1554*7b5038d7SDag-Erling Smørgrav return 1; 1555*7b5038d7SDag-Erling Smørgrav } 1556*7b5038d7SDag-Erling Smørgrav return ldns_rdf_compare(ldns_rr_owner(rr1), ldns_rr_owner(rr2)); 1557*7b5038d7SDag-Erling Smørgrav } 1558*7b5038d7SDag-Erling Smørgrav 1559*7b5038d7SDag-Erling Smørgrav void 1560*7b5038d7SDag-Erling Smørgrav ldns_rr_list_sort_nsec3(ldns_rr_list *unsorted) 1561*7b5038d7SDag-Erling Smørgrav { 1562*7b5038d7SDag-Erling Smørgrav qsort(unsorted->_rrs, 1563*7b5038d7SDag-Erling Smørgrav ldns_rr_list_rr_count(unsorted), 1564*7b5038d7SDag-Erling Smørgrav sizeof(ldns_rr *), 1565*7b5038d7SDag-Erling Smørgrav qsort_rr_compare_nsec3); 1566*7b5038d7SDag-Erling Smørgrav } 1567*7b5038d7SDag-Erling Smørgrav 1568*7b5038d7SDag-Erling Smørgrav int 1569*7b5038d7SDag-Erling Smørgrav ldns_dnssec_default_add_to_signatures( ATTR_UNUSED(ldns_rr *sig) 1570*7b5038d7SDag-Erling Smørgrav , ATTR_UNUSED(void *n) 1571*7b5038d7SDag-Erling Smørgrav ) 1572*7b5038d7SDag-Erling Smørgrav { 1573*7b5038d7SDag-Erling Smørgrav return LDNS_SIGNATURE_LEAVE_ADD_NEW; 1574*7b5038d7SDag-Erling Smørgrav } 1575*7b5038d7SDag-Erling Smørgrav 1576*7b5038d7SDag-Erling Smørgrav int 1577*7b5038d7SDag-Erling Smørgrav ldns_dnssec_default_leave_signatures( ATTR_UNUSED(ldns_rr *sig) 1578*7b5038d7SDag-Erling Smørgrav , ATTR_UNUSED(void *n) 1579*7b5038d7SDag-Erling Smørgrav ) 1580*7b5038d7SDag-Erling Smørgrav { 1581*7b5038d7SDag-Erling Smørgrav return LDNS_SIGNATURE_LEAVE_NO_ADD; 1582*7b5038d7SDag-Erling Smørgrav } 1583*7b5038d7SDag-Erling Smørgrav 1584*7b5038d7SDag-Erling Smørgrav int 1585*7b5038d7SDag-Erling Smørgrav ldns_dnssec_default_delete_signatures( ATTR_UNUSED(ldns_rr *sig) 1586*7b5038d7SDag-Erling Smørgrav , ATTR_UNUSED(void *n) 1587*7b5038d7SDag-Erling Smørgrav ) 1588*7b5038d7SDag-Erling Smørgrav { 1589*7b5038d7SDag-Erling Smørgrav return LDNS_SIGNATURE_REMOVE_NO_ADD; 1590*7b5038d7SDag-Erling Smørgrav } 1591*7b5038d7SDag-Erling Smørgrav 1592*7b5038d7SDag-Erling Smørgrav int 1593*7b5038d7SDag-Erling Smørgrav ldns_dnssec_default_replace_signatures( ATTR_UNUSED(ldns_rr *sig) 1594*7b5038d7SDag-Erling Smørgrav , ATTR_UNUSED(void *n) 1595*7b5038d7SDag-Erling Smørgrav ) 1596*7b5038d7SDag-Erling Smørgrav { 1597*7b5038d7SDag-Erling Smørgrav return LDNS_SIGNATURE_REMOVE_ADD_NEW; 1598*7b5038d7SDag-Erling Smørgrav } 1599*7b5038d7SDag-Erling Smørgrav 1600*7b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 1601*7b5038d7SDag-Erling Smørgrav ldns_rdf * 1602*7b5038d7SDag-Erling Smørgrav ldns_convert_dsa_rrsig_asn12rdf(const ldns_buffer *sig, 1603*7b5038d7SDag-Erling Smørgrav const long sig_len) 1604*7b5038d7SDag-Erling Smørgrav { 1605*7b5038d7SDag-Erling Smørgrav ldns_rdf *sigdata_rdf; 1606*7b5038d7SDag-Erling Smørgrav DSA_SIG *dsasig; 1607*7b5038d7SDag-Erling Smørgrav unsigned char *dsasig_data = (unsigned char*)ldns_buffer_begin(sig); 1608*7b5038d7SDag-Erling Smørgrav size_t byte_offset; 1609*7b5038d7SDag-Erling Smørgrav 1610*7b5038d7SDag-Erling Smørgrav dsasig = d2i_DSA_SIG(NULL, 1611*7b5038d7SDag-Erling Smørgrav (const unsigned char **)&dsasig_data, 1612*7b5038d7SDag-Erling Smørgrav sig_len); 1613*7b5038d7SDag-Erling Smørgrav if (!dsasig) { 1614*7b5038d7SDag-Erling Smørgrav DSA_SIG_free(dsasig); 1615*7b5038d7SDag-Erling Smørgrav return NULL; 1616*7b5038d7SDag-Erling Smørgrav } 1617*7b5038d7SDag-Erling Smørgrav 1618*7b5038d7SDag-Erling Smørgrav dsasig_data = LDNS_XMALLOC(unsigned char, 41); 1619*7b5038d7SDag-Erling Smørgrav if(!dsasig_data) { 1620*7b5038d7SDag-Erling Smørgrav DSA_SIG_free(dsasig); 1621*7b5038d7SDag-Erling Smørgrav return NULL; 1622*7b5038d7SDag-Erling Smørgrav } 1623*7b5038d7SDag-Erling Smørgrav dsasig_data[0] = 0; 1624*7b5038d7SDag-Erling Smørgrav byte_offset = (size_t) (20 - BN_num_bytes(dsasig->r)); 1625*7b5038d7SDag-Erling Smørgrav if (byte_offset > 20) { 1626*7b5038d7SDag-Erling Smørgrav DSA_SIG_free(dsasig); 1627*7b5038d7SDag-Erling Smørgrav LDNS_FREE(dsasig_data); 1628*7b5038d7SDag-Erling Smørgrav return NULL; 1629*7b5038d7SDag-Erling Smørgrav } 1630*7b5038d7SDag-Erling Smørgrav memset(&dsasig_data[1], 0, byte_offset); 1631*7b5038d7SDag-Erling Smørgrav BN_bn2bin(dsasig->r, &dsasig_data[1 + byte_offset]); 1632*7b5038d7SDag-Erling Smørgrav byte_offset = (size_t) (20 - BN_num_bytes(dsasig->s)); 1633*7b5038d7SDag-Erling Smørgrav if (byte_offset > 20) { 1634*7b5038d7SDag-Erling Smørgrav DSA_SIG_free(dsasig); 1635*7b5038d7SDag-Erling Smørgrav LDNS_FREE(dsasig_data); 1636*7b5038d7SDag-Erling Smørgrav return NULL; 1637*7b5038d7SDag-Erling Smørgrav } 1638*7b5038d7SDag-Erling Smørgrav memset(&dsasig_data[21], 0, byte_offset); 1639*7b5038d7SDag-Erling Smørgrav BN_bn2bin(dsasig->s, &dsasig_data[21 + byte_offset]); 1640*7b5038d7SDag-Erling Smørgrav 1641*7b5038d7SDag-Erling Smørgrav sigdata_rdf = ldns_rdf_new(LDNS_RDF_TYPE_B64, 41, dsasig_data); 1642*7b5038d7SDag-Erling Smørgrav if(!sigdata_rdf) { 1643*7b5038d7SDag-Erling Smørgrav LDNS_FREE(dsasig_data); 1644*7b5038d7SDag-Erling Smørgrav } 1645*7b5038d7SDag-Erling Smørgrav DSA_SIG_free(dsasig); 1646*7b5038d7SDag-Erling Smørgrav 1647*7b5038d7SDag-Erling Smørgrav return sigdata_rdf; 1648*7b5038d7SDag-Erling Smørgrav } 1649*7b5038d7SDag-Erling Smørgrav 1650*7b5038d7SDag-Erling Smørgrav ldns_status 1651*7b5038d7SDag-Erling Smørgrav ldns_convert_dsa_rrsig_rdf2asn1(ldns_buffer *target_buffer, 1652*7b5038d7SDag-Erling Smørgrav const ldns_rdf *sig_rdf) 1653*7b5038d7SDag-Erling Smørgrav { 1654*7b5038d7SDag-Erling Smørgrav /* the EVP api wants the DER encoding of the signature... */ 1655*7b5038d7SDag-Erling Smørgrav BIGNUM *R, *S; 1656*7b5038d7SDag-Erling Smørgrav DSA_SIG *dsasig; 1657*7b5038d7SDag-Erling Smørgrav unsigned char *raw_sig = NULL; 1658*7b5038d7SDag-Erling Smørgrav int raw_sig_len; 1659*7b5038d7SDag-Erling Smørgrav 1660*7b5038d7SDag-Erling Smørgrav if(ldns_rdf_size(sig_rdf) < 1 + 2*SHA_DIGEST_LENGTH) 1661*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_SYNTAX_RDATA_ERR; 1662*7b5038d7SDag-Erling Smørgrav /* extract the R and S field from the sig buffer */ 1663*7b5038d7SDag-Erling Smørgrav R = BN_new(); 1664*7b5038d7SDag-Erling Smørgrav if(!R) return LDNS_STATUS_MEM_ERR; 1665*7b5038d7SDag-Erling Smørgrav (void) BN_bin2bn((unsigned char *) ldns_rdf_data(sig_rdf) + 1, 1666*7b5038d7SDag-Erling Smørgrav SHA_DIGEST_LENGTH, R); 1667*7b5038d7SDag-Erling Smørgrav S = BN_new(); 1668*7b5038d7SDag-Erling Smørgrav if(!S) { 1669*7b5038d7SDag-Erling Smørgrav BN_free(R); 1670*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR; 1671*7b5038d7SDag-Erling Smørgrav } 1672*7b5038d7SDag-Erling Smørgrav (void) BN_bin2bn((unsigned char *) ldns_rdf_data(sig_rdf) + 21, 1673*7b5038d7SDag-Erling Smørgrav SHA_DIGEST_LENGTH, S); 1674*7b5038d7SDag-Erling Smørgrav 1675*7b5038d7SDag-Erling Smørgrav dsasig = DSA_SIG_new(); 1676*7b5038d7SDag-Erling Smørgrav if (!dsasig) { 1677*7b5038d7SDag-Erling Smørgrav BN_free(R); 1678*7b5038d7SDag-Erling Smørgrav BN_free(S); 1679*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR; 1680*7b5038d7SDag-Erling Smørgrav } 1681*7b5038d7SDag-Erling Smørgrav 1682*7b5038d7SDag-Erling Smørgrav dsasig->r = R; 1683*7b5038d7SDag-Erling Smørgrav dsasig->s = S; 1684*7b5038d7SDag-Erling Smørgrav 1685*7b5038d7SDag-Erling Smørgrav raw_sig_len = i2d_DSA_SIG(dsasig, &raw_sig); 1686*7b5038d7SDag-Erling Smørgrav if (raw_sig_len < 0) { 1687*7b5038d7SDag-Erling Smørgrav DSA_SIG_free(dsasig); 1688*7b5038d7SDag-Erling Smørgrav free(raw_sig); 1689*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_SSL_ERR; 1690*7b5038d7SDag-Erling Smørgrav } 1691*7b5038d7SDag-Erling Smørgrav if (ldns_buffer_reserve(target_buffer, (size_t) raw_sig_len)) { 1692*7b5038d7SDag-Erling Smørgrav ldns_buffer_write(target_buffer, raw_sig, (size_t)raw_sig_len); 1693*7b5038d7SDag-Erling Smørgrav } 1694*7b5038d7SDag-Erling Smørgrav 1695*7b5038d7SDag-Erling Smørgrav DSA_SIG_free(dsasig); 1696*7b5038d7SDag-Erling Smørgrav free(raw_sig); 1697*7b5038d7SDag-Erling Smørgrav 1698*7b5038d7SDag-Erling Smørgrav return ldns_buffer_status(target_buffer); 1699*7b5038d7SDag-Erling Smørgrav } 1700*7b5038d7SDag-Erling Smørgrav 1701*7b5038d7SDag-Erling Smørgrav #ifdef USE_ECDSA 1702*7b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S 1703*7b5038d7SDag-Erling Smørgrav ldns_rdf * 1704*7b5038d7SDag-Erling Smørgrav ldns_convert_ecdsa_rrsig_asn12rdf(const ldns_buffer *sig, const long sig_len) 1705*7b5038d7SDag-Erling Smørgrav { 1706*7b5038d7SDag-Erling Smørgrav ECDSA_SIG* ecdsa_sig; 1707*7b5038d7SDag-Erling Smørgrav unsigned char *data = (unsigned char*)ldns_buffer_begin(sig); 1708*7b5038d7SDag-Erling Smørgrav ldns_rdf* rdf; 1709*7b5038d7SDag-Erling Smørgrav ecdsa_sig = d2i_ECDSA_SIG(NULL, (const unsigned char **)&data, sig_len); 1710*7b5038d7SDag-Erling Smørgrav if(!ecdsa_sig) return NULL; 1711*7b5038d7SDag-Erling Smørgrav 1712*7b5038d7SDag-Erling Smørgrav /* "r | s". */ 1713*7b5038d7SDag-Erling Smørgrav data = LDNS_XMALLOC(unsigned char, 1714*7b5038d7SDag-Erling Smørgrav BN_num_bytes(ecdsa_sig->r) + BN_num_bytes(ecdsa_sig->s)); 1715*7b5038d7SDag-Erling Smørgrav if(!data) { 1716*7b5038d7SDag-Erling Smørgrav ECDSA_SIG_free(ecdsa_sig); 1717*7b5038d7SDag-Erling Smørgrav return NULL; 1718*7b5038d7SDag-Erling Smørgrav } 1719*7b5038d7SDag-Erling Smørgrav BN_bn2bin(ecdsa_sig->r, data); 1720*7b5038d7SDag-Erling Smørgrav BN_bn2bin(ecdsa_sig->s, data+BN_num_bytes(ecdsa_sig->r)); 1721*7b5038d7SDag-Erling Smørgrav rdf = ldns_rdf_new(LDNS_RDF_TYPE_B64, (size_t)( 1722*7b5038d7SDag-Erling Smørgrav BN_num_bytes(ecdsa_sig->r) + BN_num_bytes(ecdsa_sig->s)), data); 1723*7b5038d7SDag-Erling Smørgrav ECDSA_SIG_free(ecdsa_sig); 1724*7b5038d7SDag-Erling Smørgrav return rdf; 1725*7b5038d7SDag-Erling Smørgrav } 1726*7b5038d7SDag-Erling Smørgrav 1727*7b5038d7SDag-Erling Smørgrav ldns_status 1728*7b5038d7SDag-Erling Smørgrav ldns_convert_ecdsa_rrsig_rdf2asn1(ldns_buffer *target_buffer, 1729*7b5038d7SDag-Erling Smørgrav const ldns_rdf *sig_rdf) 1730*7b5038d7SDag-Erling Smørgrav { 1731*7b5038d7SDag-Erling Smørgrav ECDSA_SIG* sig; 1732*7b5038d7SDag-Erling Smørgrav int raw_sig_len; 1733*7b5038d7SDag-Erling Smørgrav long bnsize = (long)ldns_rdf_size(sig_rdf) / 2; 1734*7b5038d7SDag-Erling Smørgrav /* if too short, or not even length, do not bother */ 1735*7b5038d7SDag-Erling Smørgrav if(bnsize < 16 || (size_t)bnsize*2 != ldns_rdf_size(sig_rdf)) 1736*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 1737*7b5038d7SDag-Erling Smørgrav 1738*7b5038d7SDag-Erling Smørgrav /* use the raw data to parse two evenly long BIGNUMs, "r | s". */ 1739*7b5038d7SDag-Erling Smørgrav sig = ECDSA_SIG_new(); 1740*7b5038d7SDag-Erling Smørgrav if(!sig) return LDNS_STATUS_MEM_ERR; 1741*7b5038d7SDag-Erling Smørgrav sig->r = BN_bin2bn((const unsigned char*)ldns_rdf_data(sig_rdf), 1742*7b5038d7SDag-Erling Smørgrav bnsize, sig->r); 1743*7b5038d7SDag-Erling Smørgrav sig->s = BN_bin2bn((const unsigned char*)ldns_rdf_data(sig_rdf)+bnsize, 1744*7b5038d7SDag-Erling Smørgrav bnsize, sig->s); 1745*7b5038d7SDag-Erling Smørgrav if(!sig->r || !sig->s) { 1746*7b5038d7SDag-Erling Smørgrav ECDSA_SIG_free(sig); 1747*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR; 1748*7b5038d7SDag-Erling Smørgrav } 1749*7b5038d7SDag-Erling Smørgrav 1750*7b5038d7SDag-Erling Smørgrav raw_sig_len = i2d_ECDSA_SIG(sig, NULL); 1751*7b5038d7SDag-Erling Smørgrav if (ldns_buffer_reserve(target_buffer, (size_t) raw_sig_len)) { 1752*7b5038d7SDag-Erling Smørgrav unsigned char* pp = (unsigned char*) 1753*7b5038d7SDag-Erling Smørgrav ldns_buffer_current(target_buffer); 1754*7b5038d7SDag-Erling Smørgrav raw_sig_len = i2d_ECDSA_SIG(sig, &pp); 1755*7b5038d7SDag-Erling Smørgrav ldns_buffer_skip(target_buffer, (ssize_t) raw_sig_len); 1756*7b5038d7SDag-Erling Smørgrav } 1757*7b5038d7SDag-Erling Smørgrav ECDSA_SIG_free(sig); 1758*7b5038d7SDag-Erling Smørgrav 1759*7b5038d7SDag-Erling Smørgrav return ldns_buffer_status(target_buffer); 1760*7b5038d7SDag-Erling Smørgrav } 1761*7b5038d7SDag-Erling Smørgrav 1762*7b5038d7SDag-Erling Smørgrav #endif /* S_SPLINT_S */ 1763*7b5038d7SDag-Erling Smørgrav #endif /* USE_ECDSA */ 1764*7b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 1765